0
Offline
Newbie
Karma: 0
Posts: 33
Arduino rocks
|
 |
« on: April 28, 2012, 11:09:31 pm » |
I've been pounding at this all day, and I'm missing something. If somebody can point my nose I would appreciate it. I picked up a couple of RDA5807SP I2C based FM Radio Receiver IC's off the FleaBay a few days ago. They came in the mail, and I'm anxious to hook them up to my arduino. They're I2C controlled, they have a couple of registers storing what looks like 2 bytes of data each, and we can manipulate these registers to control the radio. I'm fairly new to I2C, but starting to get my feet wet, and I just can't seem to get the hang of the appropriate read/write on this thing. I write values to the registers, but when I read them back, they're different from what I wrote. I'm not sure where to go from here. See my attached code. So for example, lets say I want to write the register at 0x05, and set bits 0-3 as the value 1 (forget the other bits, they're not important yet), I'm doing whats shown below. But its not working. When I read it back, its not how I set it. What am I doing wrong? #include <Wire.h>
int device_address = 96; int seekPin = 12; int seekPinState = 0;
void setup(){ pinMode (seekPin,INPUT); Wire.begin(); Serial.begin(9600);
getVolume(); maxVolume(); getVolume();
}
void loop(){
Serial.print("Device addres is: "); Serial.println(device_address);
seekPinState = digitalRead(seekPin);
if (seekPinState == 1) { Serial.println("High!");
}
getVolume(); delay(5000);
}
void maxVolume(){ Serial.println("Setting Volume"); Wire.beginTransmission(device_address); Wire.write(5);
Wire.write(136); // first byte 10001000 Wire.write(175); // second byte 10101111 <-- This is the 1111 for the first 3 bits of the byte.
Wire.endTransmission();
}
void getVolume(){
Wire.requestFrom(device_address, 2);
while (Wire.available() == 0); int byte1 = Wire.read(); int byte2 = Wire.read(); String binaryByte1 = String(byte1, BIN); String binaryByte2 = String(byte2, BIN);
Serial.print("The currnet volume setting is: "); Serial.print(binaryByte1); Serial.print(":"); Serial.println(binaryByte2); }
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25556
Solder is electric glue
|
 |
« Reply #1 on: April 28, 2012, 11:20:04 pm » |
while (Wire.available() == 0); This just hangs about until at least one byte is available. Then:- int byte1 = Wire.read(); int byte2 = Wire.read(); Reads two bytes. At this point the second byte almost certainly has not arrived. So I would try:- while (Wire.available() < 2); I haven't looked at the rest of the code so there might be other errors as well.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #2 on: April 28, 2012, 11:24:41 pm » |
It's I2C Mike, not Serial. @op: Don't do this: while (Wire.available() == 0); Wire.requestFrom blocks until it gets the data you wanted, or it never will. Better is: if (Wire.requestFrom(device_address, 2) != 2) { // error return; } I don't know what this achieves: int byte1 = Wire.read(); int byte2 = Wire.read(); String binaryByte1 = String(byte1, BIN); String binaryByte2 = String(byte2, BIN);
Just do: byte byte1 = Wire.read(); byte byte2 = Wire.read();
Serial.print("The current volume setting is: "); Serial.print(byte1, BIN); Serial.print(":"); Serial.println(byte2, BIN);
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25556
Solder is electric glue
|
 |
« Reply #3 on: April 28, 2012, 11:26:15 pm » |
It's I2C Mike, not Serial. Yes I know, but you still have to wait until the data arrives.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 33
Arduino rocks
|
 |
« Reply #4 on: April 28, 2012, 11:26:39 pm » |
My timing must be lucky - I was getting both bytes in time... but your recommended modification is certainly a good idea, I've implemented it. So the fact remains, when I set the values, and then try to read them, they come back different. I think this is more than likely a learning curve issue... I've gotta be doing something wrong.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #5 on: April 28, 2012, 11:29:43 pm » |
Yes I know, but you still have to wait until the data arrives.
No, because requestFrom blocks. Building in the wait only makes an infinite loop possible.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #6 on: April 28, 2012, 11:33:29 pm » |
I've gotta be doing something wrong.
I've looked but I can't find the programming guide. Can you link to it please? The thing that specifies the I2C commands/responses.
|
|
|
|
|
Logged
|
|
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25556
Solder is electric glue
|
 |
« Reply #8 on: April 29, 2012, 08:09:55 am » |
The registers are 16 bit wide therefore you have to send them in two parts. That data sheet says the high byte followed by the low byte. So to send a value in a variable called val use:- Wire.write(val >> 8); // hi byte Wire.write(val & 0xff); // lo byte Values come back from the chip with the hi byte first.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 33
Arduino rocks
|
 |
« Reply #9 on: April 29, 2012, 08:59:28 am » |
Ok so we're sending it as two bytes. I get that. We're sending the high byte first - I get that. So when I create the variable that is going to be split with the code you provided, do I write it with bit 15 first or bit 0 first?
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25556
Solder is electric glue
|
 |
« Reply #10 on: April 29, 2012, 09:03:28 am » |
do I write it with bit 15 first or bit 0 first? I don't understand what you mean by first. Declare the variable as an int int var; if you want to set bit 0 then:- var = var | 0x1; or if you want to set bit 15 then:- var = var | 0x8000 The bits are the same as in a normal value.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 33
Arduino rocks
|
 |
« Reply #11 on: April 29, 2012, 09:14:23 am » |
So lets say I wanted bits 0123 to be 1's. Would I write the variable as shown in A or B
A - var = "0000000000001111" B - var = "1111000000000000"
I think I write it as A
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25556
Solder is electric glue
|
 |
« Reply #12 on: April 29, 2012, 09:17:18 am » |
I think I write it as A Yes so do I. Except don't put the value in quote marks, write it in hex.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 33
Arduino rocks
|
 |
« Reply #13 on: April 29, 2012, 09:36:14 am » |
So when you say var = var | 0x8000 is this simply starting at the position identified? Like I could write just the last 4 bits of the register if I really wanted to?
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25556
Solder is electric glue
|
 |
« Reply #14 on: April 29, 2012, 09:45:16 am » |
The | is the inclusive OR operation it is used to set those bits in the variable that are a 1 in the mask (the number you are ORing) and leave the other bits in the variable unchanged. I could write just the last 4 bits of the register if I really wanted to? If you want to set the variable to 0000000000001111 then you can just use:- var = 0xf
|
|
|
|
|
Logged
|
|
|
|
|
|