Go Down

Topic: Help neded for RF modules over SPI (Read 597 times) previous topic - next topic

robertfullagar

Feb 17, 2017, 05:51 pm Last Edit: Feb 17, 2017, 06:33 pm by robertfullagar
Hi

I have 2 CC1101 RF modules, the ones with the screw in black antennas, not springs for antenas and an Arduino Nano that I am using to build a repeater, receive on one frequency and retransmit on another.

I am using D8 for Receiver SS for the receiver and D9 for the transmitter SS, I am not using the defaut D10 as SS.

After setting D8,D9 and D10 to be OUTPUT initialising SPI (SPI.begin()) I am able to write and read the registers on the D9 device, I then make D9 High and D8 low and call exactly the same functions but I am not able to write/read to the D8 device. If I unplug the D9 device I am able to read and write the D8 device.

I have swapped devices around to ensure they are not faulty, I then powered them from another souce thinking the nano couldnt power both, same issue.

I have tried moving the D9 device to D10 and teh D8 device to D9 but the same issues are there.

I monitor the pin states during the function calls, D10 is always HIGH, when the D9 pin is HIGH D8 is LOW and vice versa.

I have peformed continuity tests from the RF devices to the nano to prove correct connectivity.

I have read the posts her on SPI and I cant figure out what I am doing wrong?

Is it a limitation of the nano that it cant support 2 spi devices?


I had to set low for each call or it wouldnt set the register correctly...

Thanks in advance

Rob


pylon

Provide a complete sketch not excerpts! You might have done something wrong elsewhere. If the complete sketch is to much code, make a shorter test sketch that has the same problem and post that one.

robertfullagar

#2
Feb 17, 2017, 11:04 pm Last Edit: Feb 17, 2017, 11:16 pm by robertfullagar
I think the only thing I omitted was the  includes at the top, the definition of some variables and the burstwritereg function ...are they necessary to get some guidance? There is a readreg function but I haven't added that as it's simply write a register value and then write a 0 and record the returned value. This is called repeatedly from the Debug function once for each register. The sspin is set to low either D9 or D8 and is passed in and set to HIGH on exit. Again this works fine for the D9 device  but not for D8 device.

If you want the transmit and interrupt receive functons they haven't been called yet so aren't applicable.

Cheers

Rob

robertfullagar

Here is all the code to date, its based on the elechouse CC1101 libraries.  I have 10k pull up resistors on the CS lines (D8 and D9) and 10k resisters to Vcc and GND for the MISO line as described in the www.dorkbotpdx.org blog

Hope someone can help :)

Cheers

Rob

pylon

Quote
Here is all the code to date, its based on the elechouse CC1101 libraries.  I have 10k pull up resistors on the CS lines (D8 and D9) and 10k resisters to Vcc and GND for the MISO line as described in the www.dorkbotpdx.org blog
The voltage divider for the MISO line is clearly described as a test mechanism for chips with badly designed SPI interface. This is not a circuit that should be used in normal operation.
The pull-ups on the CS lines is a blog author's way to remedy a lack of software knowledge with half-baked hardware modifications. My recommendation: don't use it.

To your code:

Eliminate all occurrences of this:
Code: [Select]
 while(digitalRead(MISO_PIN));

It's not needed if the hardware is correct (see above).

Code: [Select]
 Reset(CC1101_PATABLE,TSS_PIN);


but

Code: [Select]
void Reset (int SLAVEPIN, byte SRES)


I guess the reset is not doing what you intend it to do as the calling parameters don't match the routine definition.

Code: [Select]
void SpiWriteReg(byte ADDR, byte VALUE, int SLAVEPIN)
{
  SPI.beginTransaction(settingsR);
  digitalWrite(SLAVEPIN,LOW);
  while(digitalRead(MISO_PIN));
  
  SPI.transfer(ADDR);
  delay(100);
  SPI.transfer(VALUE);
  digitalWrite (SLAVEPIN, HIGH);
  SPI.endTransaction();
}


Eliminate the delay() call! In the 100ms you wait there the SPI bus can transfer 50kB of data. A chip may expect a bus failure if the delay after the register address is sent to the sending of the value is that long.

Code: [Select]
void SendData(byte *txBuffer,byte Datasize,int SLAVEPIN,int GDO0_PIN,int GDO2_PIN,byte SFTX)
{
  Serial.println("In Send Data......");
 
  digitalWrite (SLAVEPIN, LOW);
  SpiWriteReg(CC1101_TXFIFO,Datasize,SLAVEPIN);
   digitalWrite (SLAVEPIN, LOW);
  SpiWriteBurstReg(CC1101_TXFIFO,txBuffer,Datasize,SLAVEPIN);      //write data to send
   digitalWrite (SLAVEPIN, LOW);
  SpiStrobe(CC1101_STX,SLAVEPIN);                  //start send  
    while (!digitalRead(GDO0_PIN));               // Wait for GDO0 to be set -> sync transmitted  
    while (digitalRead(GDO0_PIN));                // Wait for GDO0 to be cleared -> end of packet
    digitalWrite (SLAVEPIN, LOW);
  SpiStrobe(SFTX,SLAVEPIN);                  //flush TXfifo
 
}


Introduce a timeout in the while loops to be able to react on bad transmission failures.

Code: [Select]
byte SpiReadReg(byte addr, int SSPIN)
{
  byte temp, value;

  SPI.beginTransaction(settingsR);
        temp = addr|READ_SINGLE;
       
  digitalWrite(SSPIN, LOW);
  while(digitalRead(MISO_PIN));
  SPI.transfer(temp);
  value=SPI.transfer(0);
  digitalWrite(SSPIN, HIGH);
  SPI.endTransaction();
  return value;
}

byte SpiReadStatus(byte addr, int SLAVEPIN)
{
  byte value,temp;

  temp = addr | READ_BURST;
  digitalWrite(SLAVEPIN, LOW);
  while(digitalRead(MISO_PIN));
  SPI.transfer(temp);
  value=SPI.transfer(0);
  digitalWrite(SLAVEPIN, HIGH);

  return value;
}


Please explain the lack of SPI.beginTransaction() in the second function. On a Nano the SPI.beginTransaction and SPI.endTransaction calls are not really necessary but you should use them consistently.

robertfullagar

Pylon

Thanks very much for your response.

I have made the changes you suggested and below is the output from the serial monitor..

I tried with and without the 10k resistors and got the same results...the 2nd device's registers dont seem get set and I dont appear to be able to read them.

I swapped D8 and D9 in the code and the first calls set the cc1101 and the second calls fail..I assume from that the wiring is correct for both the cc1101 modules?

The 3.3v supply on the nano can supply 150ma max...so it should be able to power both modules one in TX (max output) circa 34ma and circa 17ma in RX when at 3.3v.

Attached is the updated version of the code.

Thanks in advance

Rob

TSS_PI State After SPIinit: 1
RSS_PI State After SPIinit: 1
SS_PIN State After SPIinit: 1
TSS_PI State After Reset: 1
RSS_PI State After Reset: 1
SS_PIN State After Reset: 1
Done Radio config Settings
TSS_PI State After config radios: 1
RSS_PI State After config radios: 1
SS_PIN State After  config Radios: 1
TSS_PI State After SpiWriteBurstReg: 1
RSS_PI State After SpiWriteBurstReg: 1
SS_PIN State After  SpiWriteBurstReg: 1
TSS_PI State After GDO_Set: 1
RSS_PI State After GDO_Set: 1
SS_PIN State After  GDO_Set: 1
Starting Debug for SSPIN: 9
...
In CC1101_IOCFG0 is :6
In CC1101_FIFOTHR is :47
In CC1101_PKTCTRL0 is :5
In CC1101_FSCTRL1 is :6
In CC1101_FREQ2 is :10
In CC1101_FREQ1 is :B1
In CC1101_FREQ0 is :3B
In CC1101_MDMCFG4 is :FA
In CC1101_MDMCFG3 is :4D
In CC1101_MDMCFG2 is :37
In CC1101_DEVIATN is :15
In CC1101_MCSM0 is :18
In PaTable is :C0


Ending Debug for SSPIN: 9
...
TSS_PI State after debug: 1
RSS_PI State after debug: 1
SS_PIN State after debug: 1

End Setting up Transmitter

TSS_PI State After Reset: 1
RSS_PI State After Reset: 1
SS_PIN State After Reset: 1
Done Radio config Settings
TSS_PI State After config radios: 1
RSS_PI State After config radios: 1
SS_PIN State After  config Radios: 1
TSS_PI State After GDO_Set: 1
RSS_PI State After GDO_Set: 1
SS_PIN State After  GDO_Set: 1
Starting Debug for SSPIN: 8
...
In CC1101_IOCFG0 is :0
In CC1101_FIFOTHR is :0
In CC1101_PKTCTRL0 is :0
In CC1101_FSCTRL1 is :0
In CC1101_FREQ2 is :0
In CC1101_FREQ1 is :0
In CC1101_FREQ0 is :0
In CC1101_MDMCFG4 is :0
In CC1101_MDMCFG3 is :0
In CC1101_MDMCFG2 is :0
In CC1101_DEVIATN is :0
In CC1101_MCSM0 is :0
In PaTable is :0


Ending Debug for SSPIN: 8
...
TSS_PI State after debug: 1
RSS_PI State after debug: 1
SS_PIN State after debug: 1

End Setting up receiver

In Send Data......
Done SpiStrobe......
 


pylon

Did you change just the software or the hardware too?

I guess you use a standard Nano. Do you use a level converter for the SPI pins? If yes, please provide a link to it. Please also provide a link to the exact module you use. The CC1101 is a low voltage module. From what you write I guess you drive it with 3V3. The voltage on the SPI pins should never be higher than 3V6.

Please post a diagram of your complete wiring (or a photo of the setup where all wires are visible).

You misunderstood my sentence about the timeout:

Code: [Select]
   while (!digitalRead(GDO0_PIN)) {               // Wait for GDO0 to be set -> sync transmitted
      delay(1);                
    }
    while (digitalRead(GDO0_PIN)) {                // Wait for GDO0 to be cleared -> end of packet
      delay(1);              
    }


I didn't want you to insert delay() calls but have the loops ending even if the hardware does not what you expect it to do:

Code: [Select]

    uint32_t timeout = 200000;
    while (!digitalRead(GDO0_PIN) && timeout-- > 0);               // Wait for GDO0 to be set -> sync transmitted
    while (digitalRead(GDO0_PIN) && timeout-- > 0)                // Wait for GDO0 to be cleared -> end of packet


You're wasting a lot of RAM with the debugging strings to print to the serial interface. Use the F() macro to leave the strings in the flash memory:

Code: [Select]
Serial.print("This is my debugging string");

should get

Code: [Select]
Serial.print(F("This is my debugging string"));

This is for all calls to print() or println().

Your version uses more than three quarter of the available RAM just for constant global variables. The remaining 400 bytes are gone very fast and may be responsible for unusual symptoms.


If you

robertfullagar

#7
Feb 20, 2017, 10:34 pm Last Edit: Feb 21, 2017, 09:43 am by robertfullagar
Thanks in advance again Pylon for your response!

I just changed the pins over in the code i didnt touch the wiring.

I am not using a level converter I am powering from the +3.3v on the Nano and powering from USB on the PC (at the moment).  My RF modules are marked TI-CC1101 - http://www.ti.com/lit/ds/symlink/cc1101.pdf

Attached is a wiring diagram of how the modules are attached to the Nano.

You are right I did misunderstand you and will rectify that in the code.

I am only using the debug statementts as it doesnt work and helps me understand whats going on where, I will delete or comment out when the project is working :)

Thanks for the F() macro to save memory, I have some time tomorrow and make those changes.

I do have a couple of logic analyzer (saleae Logic 16 channel and a cheap chinese one) if all else fails I could capture some traces of SCK, MISO, MISO, SS_pin(10) RSS_PIN and TSS_PIN to help debug if you think it will help.

I could make an unused pin move from high to low a few times in the trace so we could clearly see the first devices SPI traffic and the 2nd devices?  That may or may not help identify an issue...for me it seems the Nano is being put into slave mode (some how???) after the first device is being initialised...

Cheers again

Rob


pylon

Quote
Attached is a wiring diagram of how the modules are attached to the Nano.
According to that diagram you removed the pull-up resistors from SCKL and MOSI as well as the voltage divider from MISO. Is that correct?
In the diagram you have a double usage of pin D4. As both are outputs that may damage the chips if they have a different output level set.

Quote
I could make an unused pin move from high to low a few times in the trace so we could clearly see the first devices SPI traffic and the 2nd devices?
We should see that by the CS pins already.

Quote
That may or may not help identify an issue...for me it seems the Nano is being put into slave mode (some how???) after the first device is being initialised...
I don't see a reason for that. You did set pin 10 as an output, that should be enough to direct the hardware into master mode.

robertfullagar

Pylon

Yes I did remove the resistors and voltage divider as your replpy implied they werent required, and the D4 on the receiver should be D2...my bad cut and paste error...I will double check what i have in the code. should be D4 and D5 on the ransmitter and D2 and D3 on the receiver.

What should I do next?

Cheers

Rob

pylon

Try attaching the saleae and connect the SPI bus lines and the CS signals.

Shorten the sketch to set exactly one register and read it again on each slave board. Run that sketch and trigger with a falling edge of the CS signal. Please post the output picture if triggered on the first CS and if triggered on the second CS.

Go Up