Author Topic: I2C Encoder V2 ALIVE on Kickstarter!  (Read 3633 times)

0 Members and 1 Guest are viewing this topic.

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
I2C Encoder V2 ALIVE on Kickstarter!
« on: June 28, 2018, 08:28:10 am »
The I2C Encoder is a tiny board that you can read a mechanical rotary encoder on the I2C bus.
https://www.kickstarter.com/projects/1351830006/i2c-encoder-v2?ref=t8hzgi

  • The I2C Encoder V2 supports both standard rotary encoder and the illuminated RGB encoder footprints!
  • There are also 3 configurable GPIOs that are organized with the same footprint of  RGB LED. You can use them as PWM, I/O or ADC.
  • it has also 256bytes of EEPROM.


At the end of the campaign, we will provide the HW and FW part of the project!


« Last Edit: June 30, 2018, 08:05:21 pm by Atika »
 

Offline larsdenmark

  • Regular Contributor
  • *
  • Posts: 78
  • Country: dk
Re: I2C Encoder V2_LIVE on Kickstarter!
« Reply #1 on: June 28, 2018, 06:12:10 pm »
It looks interesting!

A small question: How many bits is the ADC?

And then there is some bonus info: Apparently illuminated RGB rotary encoders is a thing! Who knew?
 

Offline BillyD

  • Regular Contributor
  • *
  • Posts: 194
  • Country: ie
Re: I2C Encoder V2_LIVE on Kickstarter!
« Reply #2 on: June 28, 2018, 06:53:11 pm »
Nice little unit. Is there any facility for encoder velocity, or click-able encoders?
 

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
Re: I2C Encoder V2_LIVE on Kickstarter!
« Reply #3 on: June 28, 2018, 07:24:11 pm »
The resolution of the ADC is 8bit
But the PIC ADC is 10bit, it's scaled to 8bit in order to use only 1 register. Of course this part it's possible to modify in the FW.

Click-able Encoders are supported, in case of normal encoder or RGB encoder. It's possible also to configure an interrupt when pressed or released.
The velocity of rotation is not calculated, the board is intended to be used by human, not motor. ;)

Thanks for the info, i will make more clear in the campaign!
 
The following users thanked this post: BillyD

Offline Kean

  • Supporter
  • ****
  • Posts: 660
  • Country: au
  • Embedded systems & IT consultant
    • Kean Electronics
Re: I2C Encoder V2_LIVE on Kickstarter!
« Reply #4 on: June 28, 2018, 10:53:26 pm »
Velocity support would be really nice.  A little tricky to get right, but very useful for some applications where you need to handle a large range of values (you do have 32-bit!) but still have the ability for fine adjustment.
 

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #5 on: June 28, 2018, 11:08:42 pm »
What you mean si something like that:
For example: if i rotate the encoder slower the increment is by 1, if i rotate a bit fast the increment is by 10 if i rotate more fast the increment is by 100

Right?
 
The following users thanked this post: BillyD, Kean

Offline Kean

  • Supporter
  • ****
  • Posts: 660
  • Country: au
  • Embedded systems & IT consultant
    • Kean Electronics
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #6 on: June 29, 2018, 02:24:30 am »
What you mean si something like that:
For example: if i rotate the encoder slower the increment is by 1, if i rotate a bit fast the increment is by 10 if i rotate more fast the increment is by 100

Right?

Exactly!  It should probably be an option that can be enabled, not the default.
 

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #7 on: June 29, 2018, 05:14:57 pm »
Yes looks interesting! ;D
I will try to implement as soon as possible

Thanks
 

Offline Kean

  • Supporter
  • ****
  • Posts: 660
  • Country: au
  • Embedded systems & IT consultant
    • Kean Electronics
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #8 on: June 29, 2018, 05:32:54 pm »
I know the hardware is open, and schematics already posted.  Do you think the firmware will also be open at some point?
 

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #9 on: June 29, 2018, 05:56:33 pm »
Of course!

Will be publish at the end of the campaign on GitHub here: https://github.com/Fattoresaimon/I2CEncoderV2

I also published the FW and the HW of the first version here: https://github.com/Fattoresaimon/i2cencoder
 
The following users thanked this post: Kean

Offline Kean

  • Supporter
  • ****
  • Posts: 660
  • Country: au
  • Embedded systems & IT consultant
    • Kean Electronics
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #10 on: June 29, 2018, 06:12:12 pm »
Great.    :-+
In that case I'll switch my pledge from 10 to 25.  And also grab some of your first version off Tindie.
 

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #11 on: June 29, 2018, 06:31:13 pm »
Great!
Thanks a lot! :-+
 

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #12 on: June 30, 2018, 08:03:52 pm »
I forgot to write that I2C Encoder V2 is fully founded in 12 hours! :-+
We still have 28 days to run. Hoping for the best!


Thanks to every one
 

Offline larsdenmark

  • Regular Contributor
  • *
  • Posts: 78
  • Country: dk
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #13 on: July 04, 2018, 05:44:46 pm »
I'm backing this project. It should give me encoders to last a lifetime. Now I just need to figure out how the RGB LEDs are going to improve my interface.
 

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #14 on: July 06, 2018, 12:16:59 am »
Thanks larsdenmark !

We reach 100 backers!  :-+

Thanks to every one!
 

Offline dunkemhigh

  • Super Contributor
  • ***
  • Posts: 1136
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #15 on: July 06, 2018, 12:35:01 am »
I couldn't resist this one either, but I couldn't figure out if it was +4 or +6 for the RGB/LED options, or if one needs both. So I added +10 to be safe...

Was that the right thing to do, or should I modify my pledge to maximise my options?
 

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #16 on: July 06, 2018, 12:51:37 am »
Thanks dunkemhigh for the pledge!

+6 is if you want the illuminated RGB Rotary encoder, the rotary encoder with the illuminated shaft.

+4 is if you want a normal encoder (without the illuminated shaft) plus a 5mm RGB LED.

With 10€ i will get both the option: 2 RGB rotary encoder and 2 standard rotary encoder. But only two I2C Encoder V2 boards!
 

Offline dunkemhigh

  • Super Contributor
  • ***
  • Posts: 1136
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #17 on: July 06, 2018, 01:00:48 am »
OK, thanks. I guess that means I need to double the number of boards, then. Should I modify my pledge or do a new pledge for just the boards?
 

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #18 on: July 06, 2018, 01:16:49 am »
If you want to increase the number of boards is more convenient to make a pledge of 5 I2C Encoder V2 boards.
There is also the offer to I2C Encoder V2 boards + 5 RGB encoder.

If you make 2 different pledge you will pay 2 time the shipping.
 

Offline dunkemhigh

  • Super Contributor
  • ***
  • Posts: 1136
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #19 on: July 06, 2018, 02:27:24 am »
Ah, good point about the shipping :)
 

Online free_electron

  • Super Contributor
  • ***
  • Posts: 6925
  • Country: us
    • SiliconValleyGarage
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #20 on: July 06, 2018, 05:57:39 am »
something that i want to see : programmable rollover and lookup tables.

for example :
---------------
limit_low = 22 ,
limit_high = 33,
rollover = false
int_on_click= true
int_on_change_only = true

the encoder now goes between 22 and 33 , does not roll over , does not underflow. for each 'change' an interrupt is generated. so 32 to 33 generates and int. 33 to 33 does NOT generate an interrupt
turn right : 22<int>,23<int> ... 31<int>,32<int>,33<int>,33<NO INT! no change>,33<NO INT! no change>,33<NO INT! no change>

-----------------------
limit_low = 22 ,
limit_high = 33,
rollover = false
int_on_click= true
int_on_change_only = false
the encoder now goes between 22 and 33 , does not roll over , does not underflow. for each 'click' an interrupt is generated. so 32 to 33 generates an int. 33 to 33 does also generate an interrupt
turn right : 22<int>,23<int> ... 31<int>,32<int>,33<int>,33<int>,33<int>,33<int>

-----------------------
limit_low = 22 ,
limit_high = 33,
rollover = true
int_on_click= true
int_on_change_only = false
turn right : 22<int>,23<int> ... 31<int>,32<int>,33<int>,22<int>,23<int> .... : the encoder now rolls over properly.

other settings

limit_low (16 bit) : lower value of the encoder <nonvolatile>
limit_up (16 bit) : upper value of the encoder <nonvolatile>
rollover : boolean : stops at limit or rolls over  <nonvolatile>
int_on_click : boolean : interrupt for every click. <nonvolatile>
int_on_change_only : boolean : only interrupts if a change in value is detected works together with int_on_click <nonvolatile>
power_on_value : nonvolatile value. this is the value applied at power-up. this allows for example to default an encoder to midpoint. <nonvolatile>
use_lookup : boolean : use a lookup table ( max 1 byte ) <nonvolatile>
table <bytes> : lookup table <nonvolatile>
current_value : current pointer value <volatile, restore from power_on_value>
current_data : current data in the table  returns table<current_pointer>
read_pointer : a byte telling me what the next data byte will be. <volatile, starts at 0 after power_on>
auto_increment_read_pointer = boolean : this allows me to stop the readpointer. <nonvolatile>

so , for example if i want to make a encoder that can cycle the letter and numbers i can give it a table containing only those ascii codes.
0 = 65 ( capital a )
1 = 66 ...
25 = 90 (Z)
26 = 48 (0)
36 = 57 (9)

table 65,66,67,68,69,70,41,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,48,49,50,51,52,53,54,55,56,57
rollover= true
limit_low = 0
limit_high=36
int_on_change=true
int_on_click=true
power_up = 26

if i now turn the scrollwheel i get an interrupt on every change. i can directly read the pointer , or the table.

i would change the memory map.
current_value should be stored at 0x00
current_data should be stored at 0x04

and use little endian format. ( least significant byte first)

this limits the amount of data i need to stream over i2c.

for example : i am only interested in the table lookup, and i know i only use 1 byte , not all 4):
i set current_read_pointer to 0x04
i set _auto_increment to false

i2c_read always returns me the data pointed at. i don't need to stream all subdata.

if i only use 1 byte of the word i dont need to perform 3 useless data transfers.

« Last Edit: July 06, 2018, 06:11:28 am by free_electron »
Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 

Online free_electron

  • Super Contributor
  • ***
  • Posts: 6925
  • Country: us
    • SiliconValleyGarage
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #21 on: July 06, 2018, 06:34:23 am »
so :register 0x04 : bit 6 :  could implement the 'int_on_click' function. called IRTURN

if is set IRINC , IRDEC and IRCLICK i will get an interrupt on INCrease, DECREASE or TURN

WRAPE=FALSE
IRINC=TRUE
IRDEC=TRUE
IRCLICK=TRUE

31<int becasue INCR>,32<int becasue INCR>,33<int becasue INCR>,33<int because IRCLICK, but no roll WRAPE=false>,33<int because IRCLICK, but no roll WRAPE=false>

needed :
read_pointer : <byte> tells my what location will be read.
readmode : [fixed , inframe, autoincrement]

for example
i2c_write(encoderi2c,readpointer,0x04)
i2c_write(encoderi2c,readmode,fixed)
i2cread (4) : give me 4 bytes. the bytes will be addresses 0x04,0x04,0x04,0x04 . the read pointer does not increment during the read. so i can stream data from 1 register. for example the adc input. if i need 16 samples i simply read 16 bytes.

i2c_write(encoderi2c,readpointer,0x04)
i2c_write(encoderi2c,readmode,inframe)

if i read now
i2cread(4) gives me the contents of 0x04,0x05,0x06,0x07 : the read_pointer increments UNTIL a STOP on i2c is received. at that point the read_pointer goes back to its initial settings.
so another read gives me again  0x04,0x05,0x06,0x07

This way i can limit the amount of i2c transactions. once the device is programmed , i lock down the 'startaddress' of the read and i get immediately what i need . if i only need 1 byte i read one byte , if i need 2 , i read 2.
------

i2c_write(encoderi2c,readmode,autoincrement)
i2cread(4) gives me again 0x04,0x05,0x06,0x07. since autoincrement is on , the readpointer does not reset.
so another i2cread(4)  now gices me 0x08 0x09 0x0a 0x0b   and so on...

Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 

Online free_electron

  • Super Contributor
  • ***
  • Posts: 6925
  • Country: us
    • SiliconValleyGarage
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #22 on: July 06, 2018, 06:45:39 am »
i just backed for 10 kits including rgb encoder
Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 

Offline Atika

  • Contributor
  • Posts: 33
  • Country: it
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #23 on: July 07, 2018, 06:40:31 am »
i just backed for 10 kits including rgb encoder

Thanks for your pledge!

If i have understood correctly your example, the rollover part is already implemented even in the first version of the I2C Encoder.
About the lookup table, it is a nice idea, i will think about it.

Anyway you don't need to read all the 4 bytes of the 32bits registers, you can read only the byte that you need.
 

Online free_electron

  • Super Contributor
  • ***
  • Posts: 6925
  • Country: us
    • SiliconValleyGarage
Re: I2C Encoder V2 ALIVE on Kickstarter!
« Reply #24 on: July 07, 2018, 06:49:03 am »
i still want the ability to generate an interrupt on every click ( even if no wraparound occurs. )

I looked at the sample i2c code and that is a bit 'heavy' on the transactions.
If i want to read 4 times the adc register i have 4 accesses in write, four transmissions o fthe required register address four restarts , and four reads and four stops.
i want to be able to circularly read without restarts and bus freeing.

to read 4 times register 9 what your code does is

<start><device_address_in_write><register number 9><restart><device_address_in_read><read_8><stop>
<start><device_address_in_write><register number 9><restart><device_address_in_read><read_8><stop>
<start><device_address_in_write><register number 9><restart><device_address_in_read><read_8><stop>
<start><device_address_in_write><register number 9><restart><device_address_in_read><read_8><stop>

This is wasting a massive amount of bus bandwidth.


what i want to do is

<start><device_address_in_write><readpointer><pointer_value 09><pointer_mode_no_increment><restart><read_8><read_8><read_8><read_8><stop>

readpointer is the address of the register holding the pointer for read operations.
next is pointer_mode register. that can have 4 settings : direct , no_increment , reset_after_stop, rollover.

So. if i do:
-------------------------------------------------
scenario 1 : reading same register over and over.

<start><device_address_in_write><read_mode><no_increment> <stop> : set the read mode to no_increment. i will always be reading the same register.
<start><device_address_in_write><readpointer><0x10> <stop> :  i tell the device my next read will come from location 0x10.

but since readpointer is followed by read_mode in the memory map i can send this in one transaction.

<start><device_address_in_write><readpointer><0x10><no_increment> <stop>
<start><device_address_in_read><read_8><read_8><read_8><stop>  . gives me 3 times the contents of register 0x10

-------------------------------------------------
case 2: reset_after_stop

<start><device_address_in_write><readpointer><0x10><reset_after_stop> <stop>
<start><device_address_in_read><read_8><read_8><read_8><stop>  . gives me  the contents of register 0x10 , 0x11 and 0x12
if i do this again
<start><device_address_in_read><read_8><read_8><read_8><stop> i get again the contents of 0x10 0x11 0x12.

in other words : the read location starts at <0x10> and increments as long as i request a byte. when a STOP or RESTART is received the readpointer goes back to 0x10 so the next read operation gets that again
<start><device_address_in_read><read_8><read_8><read_8><restart><device_address_in_read><read_8><read_8><read_8><stop>

gives me 0x10 0x11 0x12 0x10 0x11 0x12

-------------------------------------------------
case 3 :rollover operation
<start><device_address_in_write><readpointer><0x10><normal> <stop>
<start><device_address_in_read><read_8><read_8><read_8><restart><device_address_in_read><read_8><read_8><read_8><stop>
gives me 0x10 0x11 0x12 0x13 0x14 0x15. the STOP or RESTART does not reset the pointer.

------------------------------------------------
case 4 : direct
this works as normal.
Normal operation is not affected by this. the other write operations work just as intended.

i can do this
<start><device_address_in_write><0x05><restart><device_address_in_read><read_8><read_8> . this will give me contents of registers 0x05 and 0x06 (ESTATUS and GPSTATUS)
<start><device_address_in_write><0x1D><0xA><no_increment>     ' set the readpointer ( register 0x1D > to 0XA ( the LSB of CVAL ) and register 0x1E (read_mode) to  and do not increment.
<start><device_address_in_read><read_8> <stop>  gives me LSB of CVAL.

a while later :
<start><device_address_in_read><read_8> <stop> gives me the LSB of CVAL. i do not need to readdress the device in write to set the target register. it already knows.

2nd scenario
<start><device_address_in_write><0x1D><0x7><reset_after_stop> <stop>    ' set the readpointer ( register 0x1D > to 0X07 ( the MSB of CVAL ) and register 0x1E (read_mode) to 'reset_after_stop'.
<start><device_address_in_read><read_8> <read_8><read_8><read_8><Stop>  gives me the entire 32 bit of CVAL

<start><device_address_in_read><read_8> <read_8><read_8><read_8><Stop>  gives me the entire 32 bit of CVAL again. no need to readdress if i have to read 9 of these

on_i2c_interrupt :
{ for (int encoder = 1;encoder <10; encoder ++)
  {
   <start><device_address_in_read><read_8> <read_8><read_8><read_8><Stop>   
  }
}

this make my scan very fast on the bus. addressing a device clears the interrupt pin

i don't need to reprogram my target read address


---------------------

in short :

add registers 0x1D and 0x1E to the register map.
0x1D : readpointer  1 byte
0x1E : readmode 1 byte.

Logic :
Code: [Select]
on_interrupt (event)
case state :
  waitforstart : if event = startevent then state= started
  started      : if event = stopevent then state = waitforstart
                 if event = receivedbyte then
                    {
                    if byte = myaddress_write then state = addressed_in_write
                    if byte = myaddress_read then state = addressed_in_read
                    if byte = general_call .....
                    if byte = reset .....
                    }

  addressed_in_write:
   case(event)
        receivedbyte : if(first_byte)
                        then {
                              pointer = received_data
                              firstbyte = false
                             }
                        else {
                              memory(pointer) = received_data
                              pointer ++
                             }
        stop : firstbyte = true; state = waitforstart
        restart : firstbyte = true; state = started;   
        getack  : give_ack

......

  addressed_in_read:

   case (readmode)
         normal:
            case (event)
                  get_byte: {
                             sendbyte (memory(pointer))
                             pointer++
                            }
                  restart  : state = started;
                  stop     : state = waitforstart;
                  giveack  : get_ack;

         no_increment:
             case(event)
                  get_byte: {
                             sendbyte memory(readpointer)    // we send based on readpointer, always the same
                            }
                  restart  : state = started;
                  stop     : state = waitforstart;
                  giveack  : get_ack;

         reset_after_stop:
              case (event)
                  get_byte: { if (firstbyte) then {pointer = readpointer ; firstbyte= false} // assign pointer here so that intermediate write do not change beginpoint
                              sendbyte memory(pointer)
                              pointer++
                            }
                  restart : firstbyte = true ; state = started;
                  stop    : firstbyte = true ; state = waitforstart;

         

« Last Edit: July 07, 2018, 08:39:18 am by free_electron »
Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf