Shop OBEX P1 Docs P2 Docs Learn Events
i2c help, I'm a propeller newb and I need help to get the i2c running to drive — Parallax Forums

i2c help, I'm a propeller newb and I need help to get the i2c running to drive

FireHopperFireHopper Posts: 180
edited 2009-05-19 21:25 in Propeller 1
www.sparkfun.com/commerce/product_info.php?products_id=8579

It looks easy to use.. but I need a bit of help.. I looked at some of the I2c objects, but they seem to be for eeproms mostly.. not very helpfull.

thanks for any help I can get.

Comments

  • T ChapT Chap Posts: 4,223
    edited 2009-05-14 00:28
    minimali2cdriver will likely handle what you want to do.
  • FireHopperFireHopper Posts: 180
    edited 2009-05-14 00:39
    TChapman said...
    minimali2cdriver will likely handle what you want to do.

    Where is it, I didnt see it on the exchange. I'm reading the i2c demo app v2 and am reading it.. Its a bit over my head, but I'm slowly making headway
  • T ChapT Chap Posts: 4,223
    edited 2009-05-14 00:43
  • RaymanRayman Posts: 14,827
    edited 2009-05-14 00:43
    I've got a very simple I2C driver on this page:

    http://www.rayslogic.com/propeller/Programming/I2C/I2C.htm

    Someone took it and posted it to OBEX.· Normally, this would annoy me, but since it was really Mike Green's code anyway, I don't complain!

    If you search OBEX for I2C, you'll find it there too...

    Ray

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm
  • FireHopperFireHopper Posts: 180
    edited 2009-05-14 00:59
    for some reason I'm not able to wrap my head around this, maybe its due to being a bit sleepy. oh well. Maybe I'll be able to get it in the morning.
  • T ChapT Chap Posts: 4,223
    edited 2009-05-14 01:04
    If you are really new to I2c, the first step is to find out how to address it, then add the write or read bit. The address would often include the parts fixed 'ID' of so many bits, then the user defined address which may be 2 - 3 bits in length set by external pins pulled high or low in a BCD coded input fashion, then the read or write bit at the very end. There is typically a byte that gets sent to start the communication and stop it per interaction. There are also cases where, once you set a state, you may only need to send read commands afterward. Every device has it's own way to talk to it.

    Below is an example from some code I just grabbed. Note that there is first a 'start' condition that includes the SCL pin number. Then the address plus write bit. Then another byte that tells the I2C device where (the register address) to read from. After setting this info, there is a 'stop' sent. Next there is another 'start' condition, address plus READ bit (1), read the first byte, then read the next byte while putting the data into a WORD correctly using bitshift, then a STOP. After the data was read, return with the info requested. Of course what you are trying to accomplish will be different, but the datasheet will usually tell you what is required to either read or write from the device.


    
    OBJ
        i2c1         : "minimali2cdriver"
    
    
    PUB Testdevice
         repeat
           if  ReadKeyPadA > 0    'just an example of using the i2c code below
              'do something else
    
    PUB ReadKeyPadA
         i2c2.i2cStart(i2cSCL2) 'start the transaction
         i2c2.i2cWrite(i2cSCL2, KPaaddr + 0)
         i2c2.i2cWrite(i2cSCL2, 1)                ' read address
         i2c2.i2cstop(i2cSCL2)
    
         i2c2.i2cStart(i2cSCL2)
         i2c2.i2cWrite(i2cSCL2, KPaaddr + 1)            'start the read
         KPAPinInput := i2c2.i2cRead(i2cSCL2, 0)        'read first bit field 0 - 7 keys
         KPAPinInput |= i2c2.i2cRead(i2cSCL2, 1) << 8   'read second bit field 8 - 15
         i2c2.i2cStop(i2cSCL2)
         return  KPAPinInput
    

    Post Edited (TChapman) : 5/14/2009 1:09:19 AM GMT
  • FireHopperFireHopper Posts: 180
    edited 2009-05-14 01:14
    hrmm.. basicly what I need to do is send commands to the blink m's I'm going to have a lot of them eventually, and I will set each one to a seperate I2C address, eventually
    but to test it I only need to send commands to address $00 (broadcast addie)
  • T ChapT Chap Posts: 4,223
    edited 2009-05-14 01:36
    Start by reading the manual, then by converting the example code they used for the AVR to Spin:




    6.1.1     Basic Commanding 
    Commands are sent to the BlinkM&#8217;s address (or the general call address).  The bytes of the 
    command are sent one after the other. 
    Thus to send the command &#8220;{&#8216;f&#8217;,0xff,0x00,0x00}&#8221; (i.e. &#8220;Fade to full red&#8221;): 
    #include &#8220;Wire.h&#8221; 
    Wire.begin();                // set up I2C 
    Wire.beginTransmission(0x09);// join I2C bus, to BlinkM 0x09 
    Wire.send(&#8216;f&#8217;);              // &#8216;f&#8217; == fade to color 
    Wire.send(0xff);             // value for red channel 
    Wire.send(0x00);             // value for blue chan. 
    Wire.send(0x00);             // value for green chan. 
    Wire.endTransmission();      // leave I2C bus
    



    [noparse][[/noparse]/code]
    Using the minimali2cdriver I posted, it translates to something like this:
    
    CON
      _clkmode               = xtal1 + pll16x
      _xinfreq               = 5_000_000  
     
        'Physical Inputs
        i2cSCL              = 28     '<<<<<<set your actual pins here
        i2cSDA              = 29 
    
    OBJ
        i2c        : "minimali2cdriver"  
    
    
    PUB Start
          TEST    'run the i2c method below
             repeat   'stay alive
    
    
    PUB TEST
       i2c.start(i2cSCL)    'start condition    send SCL pin number
       i2c.write(i2cSCL, %0000_1000 + 0)    'send address $09 plus write bit '0'
       i2c.write(i2cSCL, "f")      'not sure here about this i2c driver sending 'f' as a ascii, may need to convert to hex first?  someone comment
       i2c.write(i2cSCL, $FF)    'value for red channel to $FF
       i2c.write(i2cSCL, $00)    'value for blue channel to $00
       i2c.write(i2cSCL, $00)    'value for green channel $00
       i2c.i2cstop(i2cSCL)      'stop condition
    
    



    Theoretically if you have everything hooked up right, you should get RED. You may be able to delete the 'f' fade line and have it still work without a fade.

    Post Edited (TChapman) : 5/14/2009 2:06:27 AM GMT
  • FireHopperFireHopper Posts: 180
    edited 2009-05-14 11:17
    from what I read, its not sent as ascii its sent as a byte, so putting the hex value of "f" should work..

    I'm going to order one or two of those blink M's so I can test code and stuff.
  • FireHopperFireHopper Posts: 180
    edited 2009-05-15 00:03
    [noparse][[/noparse]/code]
    Using the minimali2cdriver I posted, it translates to something like this:
    
    CON
      _clkmode               = xtal1 + pll16x
      _xinfreq               = 5_000_000  
     
        'Physical Inputs
        i2cSCL              = 28     '<<<<<<set your actual pins here
        i2cSDA              = 29 
    
    OBJ
        i2c        : "minimali2cdriver"  
    
    
    PUB Start
          TEST    'run the i2c method below
             repeat   'stay alive
    
    
    PUB TEST
       i2c.start(i2cSCL)    'start condition    send SCL pin number
       i2c.write(i2cSCL, %0000_1000 + 0)    'send address $09 plus write bit '0'
       i2c.write(i2cSCL, "f")      'not sure here about this i2c driver sending 'f' as a ascii, may need to convert to hex first?  someone comment
       i2c.write(i2cSCL, $FF)    'value for red channel to $FF
       i2c.write(i2cSCL, $00)    'value for blue channel to $00
       i2c.write(i2cSCL, $00)    'value for green channel $00
       i2c.i2cstop(i2cSCL)      'stop condition
    
    



    Theoretically if you have everything hooked up right, you should get RED. You may be able to delete the 'f' fade line and have it still work without a fade.

    where you have it sending $09, I think you have the binary value wrong.. that looks to be $08, should be %0000_1001 I think.



    anyway.. my blinkm's should arrive tomorrow. so I'll see if this works and hack it to do what I want
  • T ChapT Chap Posts: 4,223
    edited 2009-05-15 01:20
    Correct, hope it works out. Let us know how it goes.
  • FireHopperFireHopper Posts: 180
    edited 2009-05-15 02:15
    thanks for the help, I can see whats going on I think.. I hope this works.. I'm going to have to save my pennies, I need lots of those blinkm's and they are $12 ish each.. I cant afford to buy all I need at once.. I have to buy a few when I can afford em.. and i'm gonna need like 127 of em at least if not more [noparse]:([/noparse]
  • FireHopperFireHopper Posts: 180
    edited 2009-05-15 16:54
    they arrived, no luck so far, not sure where to put some resistors in or what value, since they are 5 volt items, and the propeller is not.. so I currently have a 1K one in between the clk and data lines.. but the things are not responding so far.. Not sure whats going wrong, the pins I am using are 22 for clk and 23 for data.

    will fiddle some more a bit later.
  • T ChapT Chap Posts: 4,223
    edited 2009-05-15 18:31
    You would need to draw your exact schematic for anyone to make a suggestion. You will need 4.7Kresistors as pullups to 3.3 Volts on both clock and data line. Not sure what you mean by 1k in between the clock and data, no need to use any 1k as the pullups are managing the voltage range. You may be able to run the device off 3.3 volts as is. Using 1k resisters in series with devices that are 5volt helps prevent a pin from blowing on the Prop, but with a pullup, the current and voltage to the Prop pins are set by the pullup resistor, not the device.

    Post Edited (TChapman) : 5/15/2009 6:42:19 PM GMT
  • FireHopperFireHopper Posts: 180
    edited 2009-05-15 19:15
    the blinkm devices need to run of 5 volts, or the leds wont light properly I'll dig around and see if I can find 2 4.7K resistors and try again.
    I'm connecting it up via the diagram in the manual, gnd, 5 volt, and sda and sclk
    sda is on 23, and scl is 22
  • T ChapT Chap Posts: 4,223
    edited 2009-05-15 19:58
    You could try 10k pullups, etc see what happens. The manual says 3-5 Volts, you could try with the 3.3 supply. The other thing is if you are going to use another supply, you may want to pull the grounds together is still having trouble.
  • FireHopperFireHopper Posts: 180
    edited 2009-05-15 20:01
    going to rebuild the propeller PEK breadboard setup and try again, just want to go to a base setup.
  • FireHopperFireHopper Posts: 180
    edited 2009-05-15 20:39
    okay, breadboarded Propeller using the i2c demo set v2.0 I see 3 i2c devices.. these are dec addresses.

    00 - broadcast blinkm
    18 - blinkm(2 of them default address.)
    160 - eeprom address.

    so I'm getting there [noparse]:)[/noparse]
    now all I need to do is to try the other code bit.
  • ratronicratronic Posts: 1,451
    edited 2009-05-15 21:27
    Firehopper, I played with one of· those, but I seemed to have lost my code after my last computer renuke! But the code Tchapman· has will work w/ these changes(test is a reserved word , so use something else(Like 'tes'))·and shift the addr of the blink m 1 addr bit up with zero as the least sgn. bit.·This works as I just tryed it. Also it works on 3.3 & 5v·(For the blinkm)·
    CON
    · _clkmode·············· = xtal1 + pll16x
    · _xinfreq·············· = 5_000_000·

    ··· 'Physical Inputs
    ··· i2cSCL············· = 0···· '<<<<<<set your actual pins here
    ··· i2cSDA············· = 1
    OBJ
    ··· i2c······· : "minimali2cdriver"················

    PUB Start
    ····· i2c.i2cstart(i2cSCL)
    ····· TES·· 'run the i2c method below
    ········ repeat·· 'stay alive

    PUB TES
    ·· i2c.i2cstart(i2cSCL)··· 'start condition··· send SCL pin number
    ·· i2c.i2cwrite(i2cSCL, %0001_0010)··· 'send address $09 plus write bit '0'
    ·· i2c.i2cwrite(i2cSCL, "n")····· 'not sure here about this i2c driver sending 'f' as a ascii, may need to convert to hex first?· someone comment
    ·· i2c.i2cwrite(i2cSCL, $FF)··· 'value for red channel to $FF
    ·· i2c.i2cwrite(i2cSCL, $00)··· 'value for blue channel to $00
    ·· i2c.i2cwrite(i2cSCL, $00)··· 'value for green channel $00
    ·· i2c.i2cstop(i2cSCL)····· 'stop condition


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Fix it, if it ain't broke·
    D Rat


    Dave Ratcliff· N6YEE

    Post Edited (ratronic) : 5/15/2009 10:03:50 PM GMT
  • FireHopperFireHopper Posts: 180
    edited 2009-05-16 00:06
    and yes that code works.. I'm having issues with trying to set new addresses for them

    everything else seems to work though
  • ratronicratronic Posts: 1,451
    edited 2009-05-16 02:49
    Firehopper, using all the stuff from above, this is what to send to a single blinkm to change address's one at a time.

    pub set························································································
    · i2c.i2cstart(i2cSCL)······················ 'start condition··· send SCL pin number······························
    · i2c.i2cwrite(i2cSCL, %0000_0000)··· 'send general call address of '0'························
    · i2c.i2cwrite(i2cSCL, "A")·················'send·set address command of·'A'
    · i2c.i2cwrite(i2cSCL, %0000_1001)··· 'new address you want (x09) for blinkm···················
    · i2c.i2cwrite(i2cSCL, $d0)················'send 'd0'
    · i2c.i2cwrite(i2cSCL, $0d)················'send '0d'
    · i2c.i2cwrite(i2cSCL, %0000_1001)··· 'new address you want (x09)for blinkm (repeated)
    · i2c.i2cstop(i2cSCL)······················· 'stop condition·····················································


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Fix it, if it ain't broke·
    D Rat


    Dave Ratcliff· N6YEE
  • FireHopperFireHopper Posts: 180
    edited 2009-05-16 11:28
    I was trying that, managed to get both blinkm's I have set to 0000_0001 now. just need to set one at a time.
    once I do that, then I can setup a program to do that one at a time for each one I get.
  • ratronicratronic Posts: 1,451
    edited 2009-05-16 12:51
    Firehopper, just make sure there is only one blinkm hooked up when you set the seperate· addresses, then hook them all back up and you'll be good to go!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Fix it, if it ain't broke·
    D Rat


    Dave Ratcliff· N6YEE
  • FireHopperFireHopper Posts: 180
    edited 2009-05-19 21:25
    CON
      _clkmode               = xtal1 + pll16x
      _xinfreq               = 5_000_000 
     
        'Physical Inputs
        i2cSCL              = 0     '<<<<<<set your actual pins here
        i2cSDA              = 1
    OBJ
        i2c        : "minimali2cdriver"                
    
    PUB Start
        
          TES   'run the i2c method below
             repeat   'stay alive
    
    PUB TES
       i2c.i2cstart(i2cSCL)    'start condition    send SCL pin number
       i2c.i2cwrite(i2cSCL, %0000_0000)    'send address $00 plus write bit '0'
       i2c.i2cwrite(i2cSCL, "o")      'stop all scripts
       i2c.i2cstop(i2cSCL)
    
       waitcnt(clkfreq / 10 + cnt)
       
       i2c.i2cstart(i2cSCL)    'start condition    send SCL pin number
       i2c.i2cwrite(i2cSCL, %0000_0010)    'send address $01 plus write bit '0'
       i2c.i2cwrite(i2cSCL, "n")      'send the command to set color right away, no fade. 
       i2c.i2cwrite(i2cSCL, $ff)    'value for red channel 
       i2c.i2cwrite(i2cSCL, $ff)    'value for green channel 
       i2c.i2cwrite(i2cSCL, $ff)    'value for blue channel 
       i2c.i2cstop(i2cSCL)      'stop condition
    
       waitcnt(clkfreq / 10 + cnt)
       
       i2c.i2cstart(i2cSCL)
       i2c.i2cwrite(i2cSCL, %0000_0100)    'send address $02 plus write bit '0'
       i2c.i2cwrite(i2cSCL, "n")      'send the command to set color right away, no fade. 
       i2c.i2cwrite(i2cSCL, $01)    'value for red channel 
       i2c.i2cwrite(i2cSCL, $01)    'value for green channel 
       i2c.i2cwrite(i2cSCL, $01)    'value for blue channel 
       i2c.i2cstop(i2cSCL)      'stop condition
    



    this now works.. I had to use this code to set each blinkm's address..

    CON
      _clkmode               = xtal1 + pll16x
      _xinfreq               = 5_000_000 
     
        'Physical Inputs
        i2cSCL              = 0     '<<<<<<set your actual pins here
        i2cSDA              = 1
    OBJ
        i2c        : "minimali2cdriver"                
    
    PUB Start
          i2c.i2cstart(i2cSCL)
          TES   'run the i2c method below
             repeat   'stay alive
    
    PUB TES
    
       i2c.i2cstart(i2cSCL)    'start condition    send SCL pin number
       i2c.i2cwrite(i2cSCL, %0000_0000)    'send address $09 plus write bit '0'
       i2c.i2cwrite(i2cSCL, "A")      'send the command to set color right away, no fade. 
       i2c.i2cwrite(i2cSCL, $01)    'value for red channel 
       i2c.i2cwrite(i2cSCL, $d0)    'value for green channel 
       i2c.i2cwrite(i2cSCL, $0d)    'value for blue channel 
       i2c.i2cwrite(i2cSCL, $01)    'value for blue channel
       i2c.i2cstop(i2cSCL)      'stop condition
    




    it does work. so I'm happy.. I think my issue with the address set was that I was using f11 which put it in eeprom, so that as soon as I powered it up with both blinkm's installed. it would set both again [noparse]:)[/noparse] so when I do the set address I'm doing it as f10, which only programmed the ram.
Sign In or Register to comment.