Pages: [1] 2 3   Go Down
Author Topic: RDA5807SP FM Radio Receiver - i2C  (Read 7196 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?

Code:
#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 Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
while (Wire.available() == 0);
This just hangs about until at least one byte is available.
Then:-
 
Code:
 
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:-
Code:
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
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18767
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It's I2C Mike, not Serial.

@op:

Don't do this:

Code:
 while (Wire.available() == 0);

Wire.requestFrom blocks until it gets the data you wanted, or it never will. Better is:

Code:
if (Wire.requestFrom(device_address, 2) != 2)
  {
  // error
  return;
  }

I don't know what this achieves:

Code:
 int byte1 = Wire.read();
  int byte2 = Wire.read();
  String binaryByte1 = String(byte1, BIN);
  String binaryByte2 = String(byte2, BIN);

Just do:
Code:
 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 Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It's I2C Mike, not Serial.
Yes I know, but you still have to wait until the data arrives.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18767
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18767
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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


0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The chip is the same as the FM receiver that Parallax sells, so I've been using their datasheet and example code as reference.

http://www.parallax.com/portals/0/downloads/docs/prod/audiovis/27984-FM-RadioReceiver-v1.0.pdf
http://www.parallax.com/portals/0/downloads/docs/prod/audiovis/ParallaxFMRadio-spin.zip

Some additional things I don't quite 'get' ....   When I send a bitstream to try and write the register, do I send it with bit 7 first, then 6, 5, etc (like you'd write it in binary on paper)  or does it go LSB first (unlike how you'd write it on paper). Do I have to send it one byte at a time, or can I send the full two bytes at once?  I think if I can get my arms around the proper way to read and write the registers, I'll be home free.

Thx
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:-
Code:
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 Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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
Code:
int var;
if you want to set bit 0 then:-
Code:
var = var | 0x1;
or if you want to set bit 15 then:-
Code:
var = var | 0x8000
The bits are the same as in a normal value.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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 Offline
Newbie
*
Karma: 0
Posts: 33
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Quote
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

Pages: [1] 2 3   Go Up
Jump to: