Page 1 of 1

[NXC] Please help me using an ADC over I2C

Posted: 31 Aug 2011, 12:26
by knutselman
Hello,

Some time ago I've made a sensor using the ADS7828 A/D converter. It has 8 input channels. Datasheet: http://www.ti.com/lit/ds/symlink/ads7828.pdf

In the datasheet is an explanation of how to use it on I2C, but I can't get it to work on NXC, because I don't know how the commands in NXC exactely work. I don't find any usefull examples of using I2C in NXC either. :cry:

Update: So far I've come up with this, but it doesn't work...

Code: Select all

 
byte CMD_Read[] = {0x90, 0x84};
 byte CMD_StartWrite[] = {0x91};
 byte cnt = 18;
 byte inBuffer[];
 char result;
 bool BResult;
 string resultBuffer;

 task main() {
      SetSensorLowspeed(S1);
      result = I2CWrite(S1, 2, CMD_Read);
      Wait(10);
      if (result == NO_ERR){
       TextOut(0, LCD_LINE1, "Write OK!");
      }
      BResult = I2CBytes(S1, CMD_StartWrite, cnt, inBuffer);
      result = I2CStatus(S1, cnt);
      if (result == NO_ERR){
       TextOut(0, LCD_LINE2, "Bytes OK!");
      }
      resultBuffer = ByteArrayToStr(inBuffer);
      TextOut(0, LCD_LINE4, resultBuffer);
      Wait(SEC_5);
 }
It does show Write OK!, but it doesn't display Bytes OK!.


Does anyone knows how to access the values of the ADC in NXC?

Help is much appreciated!

Thank you,
Knutselman

Re: [NXC] Please help me using an ADC over I2C

Posted: 01 Sep 2011, 02:14
by afanofosc
I assume that you are able to use this sensor with the NXT via some other programming language? If you have then I can definitely tell you how to do it in NXC if you show me how you do it with another language. What is the I2C address? I assume it is 0x90?

Both mindsensors.com and HiTechnic have a lot of sample code that shows how to make I2C calls to their devices using NXC.

John Hansen

Re: [NXC] Please help me using an ADC over I2C

Posted: 01 Sep 2011, 15:24
by knutselman
I don't know any other languages besides NXC (other than NXT-G, ofcourse).

I have looked in their examples, but they are all different than the methode to access the data described in the datasheet. By the way, it's a homemade sensor (like the mindsensor's line sensor, but less advanced & cheaper), so no one has used it before. I am pretty sure that the sensor design works, because I have once had a response in the 'Watch The Brick' console in BricxCC, but that's a long time ago and I don't remember how I did it.

Thanks in advance,

Knutselman

Re: [NXC] Please help me using an ADC over I2C

Posted: 01 Sep 2011, 18:52
by mattallen37
For reading and writing I2C registers of most I2C devices, this NXC lib works great:

Code: Select all

void MyI2CRead(byte port, byte addr, byte reg, byte cnt, byte& outbuf[])
{
  byte cmdbuf[];  // register number holder
	int             loop;
	byte            nByteReady = 0;

  ArrayBuild(cmdbuf, addr, reg);

  loop = STAT_COMM_PENDING;              //Wait until bus is free
  while (loop == STAT_COMM_PENDING ){    //        ''
    loop = I2CStatus(port, nByteReady);  //        ''
  }                                      //        ''

  I2CBytes(port, cmdbuf, cnt, outbuf)    //Read the registers
}

void MyI2CWrite(byte port, byte addr, byte reg, byte data[])
{
  byte cmdbuf[];                         //register data
  int loop, n, nByteReady;

  ArrayBuild(cmdbuf, addr, reg, data);

  loop = STAT_COMM_PENDING;              //Wait until bus is free
  while (loop == STAT_COMM_PENDING ){    //        ''
    loop = I2CStatus(port, nByteReady);  //        ''
  }                                      //        ''
  
  n = I2CWrite(port, 0, cmdbuf);        //When the I2C bus is ready, send the message you built
  while (I2CStatus(port, nByteReady) ==  STAT_COMM_PENDING); //Wait until bus is free
}
You can either copy and paste into each program that needs it, or you can #include it in all the programs you need it in.

I don't know if it will work for the IC you are using, but it works for (IIRC) everything I have tried it with.

Also remember that the I2C address according to lego programming is written differently than some. For example, if the sensor is said to have the address of 0x07, it is 0x0E in lego programming. This difference comes from the fact that some people read the address from just bits 1-7 (of 0-7), and some (like lego) read it from 0-7. Bit 0 of the address byte (as you should know) is the read/write bit.

Re: [NXC] Please help me using an ADC over I2C

Posted: 01 Sep 2011, 19:40
by knutselman
Ok, I tried it and it doesn't work, but I don't think this ADC works with registers???

I think that the datasheet means this for recieving data:

1) Send a START condition
2) Send the address WITH the write bit (in my case 0x90)
3) Recieve Acknowledge (SDA Low)
4) Send the command-byte (0x84 in my case for CH0)
5) Wait again for acknowledge
6) Resend START condition
7) Send address WITH the read bit (in my case 0x91)
8) Recieve Acknowledge
9) Recieve first byte of data
10) Recieve acknowledge
11) Recieve second byte of data
12) Recieve not-acknowledge
13) Send STOP condition

- Are these start and stop conditions send automatically?
- What are those acknowledge bits? I remember of having 0x15 (witch is B1111) returned in the 'Watch the brick' console once, but I can't make that happen again...
Even the US sensor doesn't work anymore in the 'Watch the Brick' console.
- Does the proces of 1-5 happen every time you request the data from another channel or every time you request data?
- How is this possible in NXC?

This is the first time I work with I2C, so sorry for these (propably stupid) questions.

Thank you,

Knutselman

Re: [NXC] Please help me using an ADC over I2C

Posted: 02 Sep 2011, 03:04
by afanofosc
All of that low level I2C stuff happens way down in the bowels of the NXT firmware and user programs have no control at all over how that works. I have never seen an I2C device which doesn't involve writing commands to a specific I2C register on an I2C device having a specific I2C address. The first thing to figure out is what the right I2C address is. Probably 0x90 but I wouldn't bet money on it. Then we need to figure out the register address. Maybe it is 0x00 but we need to know that value. Then the command is probably the combined bit values described in the PDF file. Maybe we write 0x90, 0x00, Cmd and ask for 2 bytes and it just works. Seems questionable but maybe.

John Hansen