cc1101 + arduino

Bonjour,

Je galère depuis quelques jours pour interfacer un rf1100se (HC-06 Arduino Bluetooh Bee Bluetooth Wireless Module - Free shipping - DealExtreme) et un arduino.
Le rf1100se est un transceiver à base de CC1101 de Texas Instrument (http://www.ti.com/lit/ds/symlink/cc1101.pdf).

J'utilise la librairie panstamp (Google Code Archive - Long-term storage for Google Code Project Hosting.).

Ci dessous mon code.
Le code reste bloqué sur le sendata.

Ci dessous mon branchement (trouvé quelquepart sur google) dont je ne suis pas sur quoique semble t il cohérent avec cette page : SPI - Arduino Reference .

Une aide me serait fort bienvenue :slight_smile:

/Erwan

Arduino GND CC1101 GND
Arduino VCC (+3.3v) CC1101 VCC
Arduino 10 CC1101 CSN (SS)
Arduino 11 CC1101 SI (MOSI)
Arduino 12 CC1101 SO (MISO)
Arduino 13 CC1101 SCK

#include "EEPROM.h"
#include "cc1101.h"

CC1101 cc1101;

// The LED is wired to the Arduino Output 4 (physical panStamp pin 19)
#define LEDOUTPUT 4

// counter to get increment in each loop
byte counter;

/**

  • Let the LED Output blink one time.
  • With small pause after the blink to see two consecutive blinks.
    */
    void blinker(){
    digitalWrite(LEDOUTPUT, HIGH);
    delay(100);
    digitalWrite(LEDOUTPUT, LOW);
    delay(100);
    }

/**

  • The setup method gets called on start of the system.
    */
    void setup()
    {
    Serial.begin(38400);
    Serial.println("start");

// setup the blinker output
pinMode(LEDOUTPUT, OUTPUT);
digitalWrite(LEDOUTPUT, LOW);

// blink once to signal the setup
blinker();

// reset the counter
counter=0;

// initialize the RF Chip
cc1101.init();
Serial.println("device initialized");
Serial.println("done");
}

/**

  • The loop method gets called on and on after the start of the system.
    */
    void loop()
    {
    Serial.println("loop");

CCPACKET data;
data.length=1;
byte blinkCount=counter++;
data.data[0]=blinkCount;
if(cc1101.sendData(data)){
Serial.print("ok ");
Serial.println(blinkCount);
for(int j=0; j<blinkCount; j++){
blinker();
}
}else{
Serial.print("failed ");
Serial.println(blinkCount);
blinker();
blinker();
}
Serial.println("loop done");
delay(2000);
}

pas mieux avec la lib elechouse :frowning:

je vais creuser coté registres présent...

si qq'un sur ce forum à déja branché un rf11000se ou encore un cc1101 ou cc1100...

/erwan

Le pin 10 c'est le Slave Select de l'Arduino, quand elle est maître il faut prendre n'importe quel pin digital et le passer à l'état bas quand on veut dialoguer avec l'esclave ainsi "désigné"

merci pour ce retour !

concrètement que dois je faire?
mon cs est bien sur le pin 10 : je dois le passer en low dans mon setup?
ou alors, je laisse mon cs sur le 10 et je passe n'importe quel autre pin en low? ce que je fais déja sur le pin 4 (ma led).

/erwan

Nan pas le 10, ça risque de fortement perturber le SPI de l'Atmega (il va "s'auto-selectionner").

Il faut voir comment fonctionne la lib : à mon avis il y a un paramétrage du pin SS, ainsi ensuite c'est transparent pour l'utilisateur et ça évite des lignes supplémentaire dans le code, ce qui est un peu le but d'une librairie xD

Ci dessous la fonction init de la librairie cc1101.
Je vois qu'il est question du pin GD0 hors je zap ce pin pour l'instant : je n'ai branché que MISO, MOSI, SS et SCK (en plus du VDD/GND bien sur).
A quoi servent les ports GD0 et GD1?

void CC1101::init(void)
{
spi.init(); // Initialize SPI interface
pinMode(GDO0, INPUT); // Config GDO0 as input
reset(); // Reset CC1101
// Configure PATABLE
writeBurstReg(CC1101_PATABLE, (byte*)paTable, 8);
}

et dans la fonction reset appelée depuis l'init je vois
...
wait_Miso(); // Wait until MISO goes low
spi.send(CC1101_SRES); // Send reset command strobe
wait_Miso(); // Wait until MISO goes low
...

Cela veut t il dire que je dois passer le pin MISO en low 2 fois de suite dans mon setup?

Pas facile :slight_smile:
Je vois que plusieurs threads ont été démarrés sur ce forum sur le cc1101 mais sans solution au final pour l'instant.

Le rf1100se semble être un bon transceiver pour pas (trop) cher : ce serait pratique d'avoir une solution arduino+rf1100se :slight_smile:

/erwan

Oué enfin c'est pas du classiques ces modules : généralement on utilise soit des nrf24l01+, ou des module en 433 mhz.

Pour ta lib j'ai trouvé ça :

Dans cc1101.cpp :

// Select (SPI) CC1101
#define cc1101_Select()  bitClear(PORT_SPI_SS, BIT_SPI_SS)
// Deselect (SPI) CC1101
#define cc1101_Deselect()  bitSet(PORT_SPI_SS, BIT_SPI_SS)

Puis dans spi.h :

#define PORT_SPI_SS  PORTB
#define BIT_SPI_SS   2

Donc par défaut le SS du cc1101 est le pin 2 du port B soit le ... 10 :s donc j'y pige rien ... Mais ça à l'air très complexe cette histoire ! tu te lances dans un sacré truc ...

PS : pense à mettre ton code entre les balises code (bouton # dans le menu reply)

En fait j'ai déjà implémenté des modules émetteurs ou récepteurs rf433 avec succès.
Le pb est que la portée est pas terrible, même en rajoutant une antenne.
De plus, ces modèles sont très sensibles au bruit.

J'aurais peut être du acheter un nrf24l01 :slight_smile:

Mais le cc1101 me plait bien pour plusieurs raisons (en théorie pour l'instant):
-differentes frequences 433,868,915 ... (a valider)
-bonne portée / pas trop sensible au bruit

De plus c'est la puce que l'on retrouve sur un RFBee qui grosso modo est un atmel 328 + cc1101, donc je me disais que ca devrait normalement le faire :slight_smile:

Mon projet a terme est de recuperer ma conso compteur d'eau qui se trouve a 20/30 metres.

La partie code du reflecteur (pour compter les tours) est fonctionelle, me reste à gérer la partie radio avec ce cc1101.

Je continue mes recherches et partagerais ici donc.

Merci,
Erwan.

Tu peux trouver des modules nrf avec amplificateur de puissance (portée annoncée en champ libre = 1000m, sans ampli = 100m). Le 2.4 Ghz a plus de mal avec les murs que le 433 mhz. Après les 433 c'est comme le reste : tout est affaire de puissance.

Des nrf c'est 2.5€ le module, au pire c'est pas la grosse perte et ça servira toujours

je continue à partager mon expérience sur le rf1100se / cc1101.

Apres avoir configuré les registres ca se comporte un peu mieux :
-le 1er senddata ne bloque plus mais me renvoie un failed
-le 2eme senddata bloque mais je crois que c'est le comportement normal a moins de modifier le bon flag

j'ai vérifié quelques registres en lecture, je retrouve bien mes valeurs passées en écriture, donc coté SPI tout va bien à priori.

Un module complexe mais qui offre plein d'options possibles.

Prochaine étape : un senddata avec succès :slight_smile:

ci dessous la sortie sur mon serial

start
initializing...
device initialized
loop...
sent failed :(0
loop done
loop...

ci dessous le code

#include "EEPROM.h"
#include "cc1101.h"

CC1101 cc1101;

// The LED is wired to the Arduino Output 4
#define LEDOUTPUT 4

// counter to get increment in each loop
byte counter;
byte b;

// PATABLE (0 dBm output power)
//char paTable[] = {0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// PATABLE (10 dBm output power)
char paTable[] = {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/**
* Let the LED Output blink one time.
* 
* With small pause after the blink to see two consecutive blinks. 
*/
void blinker(){
      digitalWrite(LEDOUTPUT, HIGH);
      delay(100);
      digitalWrite(LEDOUTPUT, LOW);
      delay(100);
}

void config()
{
cc1101.writeReg(CC1101_FSCTRL1, 0x06); //0x06,  // FSCTRL1       Frequency Synthesizer Control - IF:152.343Khz
cc1101.writeReg(CC1101_IOCFG0, 0x07);  //0x07,  // IOCFG0        GDO0 Output Pin Configuration - Packet received and CRC OK  
cc1101.writeReg(CC1101_FSCTRL0, 0x00); //0x00,  // FSCTRL0       Frequency Synthesizer Control - Freq offset
cc1101.writeReg(CC1101_FREQ2, 0x10); //0x10,  // FREQ2         Frequency Control Word, High Byte - 433.999 Mhz
cc1101.writeReg(CC1101_FREQ1, 0xb1); //0xB1,  // FREQ1         Frequency Control Word, Middle Byte
cc1101.writeReg(CC1101_FREQ0, 0x3b);  //0x3B,  // FREQ0         Frequency Control Word, Low Byte
cc1101.writeReg(CC1101_MDMCFG4, 0xf8); //0xF8,  // MDMCFG4       Modem Configuration - BW: 58.035Khz
cc1101.writeReg(CC1101_MDMCFG3, 0x83);  //0x83,  // MDMCFG3       Modem Configuration - 9595 Baud  
cc1101.writeReg(CC1101_MDMCFG2, 0x13); //0x13,  // MDMCFG2       Modem Configuration - 30/32 sync word bits - Manchester disable - GFSK - Digital DC filter enable
cc1101.writeReg(CC1101_MDMCFG1, 0x22); //0x22,  // MDMCFG1       Modem Configuration - num of preamble bytes:4 - FEC disable
cc1101.writeReg(CC1101_MDMCFG0, 0xf8); //0xF8,  // MDMCFG0       Modem Configuration - Channel spacing: 199.951Khz
cc1101.writeReg(CC1101_CHANNR, 0x00); //0x00,  // CHANNR        Channel Number
cc1101.writeReg(CC1101_DEVIATN, 0x15);  //0x15,  // DEVIATN       Modem Deviation Setting - 5.157Khz   
cc1101.writeReg(CC1101_FREND1, 0x56); //0x56,  // FREND1        Front End RX Configuration 
cc1101.writeReg(CC1101_FREND0, 0x10); //0x10,  // FREND0        Front End TX Configuration
cc1101.writeReg(CC1101_MCSM0, 0x18); //0x18,  // MCSM0         Main Radio Control State Machine Configuration - PO timeout: 64(149-155us) - Auto calibrate from idle to rx/tx
cc1101.writeReg(CC1101_FOCCFG, 0x16); //0x16,  // FOCCFG        Frequency Offset Compensation Configuration   
cc1101.writeReg(CC1101_BSCFG, 0x6c); //0x6C,  // BSCFG         Bit Synchronization Configuration
cc1101.writeReg(CC1101_AGCCTRL2, 0x03); //0x03,  // AGCCTRL2      AGC Control - target amplitude: 33dB - Maximum possible LNA + LNA 2 gain - All gain settings can be used
cc1101.writeReg(CC1101_AGCCTRL1, 0x40); //0x40,  // AGCCTRL1      AGC Control - LNA gain decreased first
cc1101.writeReg(CC1101_AGCCTRL0, 0x91); //0x91,  // AGCCTRL0      AGC Control - Medium hysterisis - Filter Samples: 16 - Normal AGC operation 
cc1101.writeReg(CC1101_FSCAL3, 0xe9); //0xE9,  // FSCAL3        Frequency Synthesizer Calibration   
cc1101.writeReg(CC1101_FSCAL2, 0x2a); //0x2A,  // FSCAL2        Frequency Synthesizer Calibration
cc1101.writeReg(CC1101_FSCAL1, 0x00); //0x00,  // FSCAL1        Frequency Synthesizer Calibration
cc1101.writeReg(CC1101_FSCAL0, 0x1f); //0x1F,  // FSCAL0        Frequency Synthesizer Calibration
cc1101.writeReg(CC1101_FSTEST, 0x59); //0x59,  // FSTEST        Frequency Synthesizer Calibration Control
cc1101.writeReg(CC1101_TEST2, 0x88); //0x88,  // TEST2         Various Test Settings
cc1101.writeReg(CC1101_TEST1, 0x31); //0x31,  // TEST1         Various Test Settings
cc1101.writeReg(CC1101_TEST0, 0x09); //0x09,  // TEST0         Various Test Settings
cc1101.writeReg(CC1101_FIFOTHR, 0x07); //0x07,  // FIFOTHR       RX FIFO and TX FIFO Thresholds - Bytes in TX FIFO:33 - Bytes in RX FIFO:32
cc1101.writeReg(CC1101_IOCFG2, 0x06); //0x06,  // IOCFG2        GDO2 Output Pin Configuration - Sync word received/sent - end of packet
cc1101.writeReg(CC1101_PKTCTRL1, 0x04); //0x04,  // PKTCTRL1      Packet Automation Control - No address check - Automatic flush of RX FIFO is disable - sync word is always accepted
cc1101.writeReg(CC1101_PKTCTRL0, 0x05); //0x05,  // PKTCTRL0      Packet Automation Control - whitening is off - RX/TX data normal mode - CRC calculation in TX and CRC check in RX - Variable packet length
cc1101.writeReg(CC1101_ADDR, 0x00); //0x00,  // ADDR          Device Address 
cc1101.writeReg(CC1101_PKTLEN, 0xff); //0xFF,  // PKTLEN        Packet Length
cc1101.writeReg(CC1101_MCSM1, 0x3f); //0x3F,  // MCSM1         Main Radio Control State Machine Configuration
// 
cc1101.writeReg(CC1101_PATABLE, paTable[0]);

}
/**
* The setup method gets called on start of the system.
*/
void setup()
{
  Serial.begin(38400);
  Serial.println("start");

  // setup the blinker output
  pinMode(LEDOUTPUT, OUTPUT);
  digitalWrite(LEDOUTPUT, LOW);

  // blink once to signal the setup
  blinker();
  
  // reset the counter
  counter=0;
  Serial.println("initializing...");
  // initialize the RF Chip
  cc1101.init();
  config();
  /*
  b=cc1101.readReg(CC1101_FREQ0, CC1101_CONFIG_REGISTER);
  Serial.println(b);
  b=cc1101.readReg(CC1101_FREQ1, CC1101_CONFIG_REGISTER);
  Serial.println(b);  
  b=cc1101.readReg(CC1101_FREQ2, CC1101_CONFIG_REGISTER);
  Serial.println(b);
  */
  //cc1101.setCarrierFreq(CFREQ_433);
  cc1101.setTxState();
  Serial.println("device initialized");
  //Serial.println("done");
}

/**
* The loop method gets called on and on after the start of the system.
*/
void loop()
{
  Serial.println("loop...");
  
  CCPACKET data;
  data.length=1;
  byte blinkCount=counter++;
  data.data[0]=blinkCount;
  
  if(cc1101.sendData(data)){
    Serial.print("sent ok :)");
    Serial.println(blinkCount);
    for(int j=0; j<blinkCount; j++){
      blinker();
    }
  }else{
    Serial.print("sent failed :(");
    Serial.println(blinkCount);    
    blinker();
    blinker();
  }  
  Serial.println("loop done");    
  delay(1000);
}

Les suites de mon aventure avec une puce radio cc1101 et un arduino :slight_smile:

Après avoir regardé de plus près la fonction senddata de la librairie panstamp (cc1101.cpp) il est apparu que cette fonction attends un retour détat depuis le port GD0 qui doit se brancher sur le port 2 de l'arduino.

Donc j'ai laissé tombé la piste des registres et repris le code depuis zero.
Et ca marche : je peux envoyer des données d'une puce à l'autre :slight_smile:
Me reste maintenant à explorer les possibilités : différentes fréquences, interfacer avec mes modules rf433 (chacon), avec mon rfxcom usb 433 transceiver, etc

On résume donc les branchements :

Arduino GND <-> CC1101 GND
Arduino VCC (+3.3v) <-> CC1101 VCC
Arduino 10 <-> CC1101 CSN (SS)
Arduino 11 <-> CC1101 SI (MOSI)
Arduino 12 <-> CC1101 SO (MISO)
Arduino 13 <-> CC1101 SCK
Arduino 02 <-> CC1101 GD0

En espérant que ca puisse aider d'autres amateurs, ci dessous le code pour la partie emetteur et recepteur.

#include "EEPROM.h"
#include "cc1101.h"

CC1101 cc1101;

#define LEDOUTPUT 7

// counter to get increment in each loop
byte counter;
byte b;
byte syncWord = 199; 

void blinker(){
      digitalWrite(LEDOUTPUT, HIGH);
      delay(100);
      digitalWrite(LEDOUTPUT, LOW);
      delay(100);
}

void setup()
{
  Serial.begin(38400);
  Serial.println("start");

  // setup the blinker output
  pinMode(LEDOUTPUT, OUTPUT);
  digitalWrite(LEDOUTPUT, LOW);

  // blink once to signal the setup
  blinker();
  
  // reset the counter
  counter=0;
  Serial.println("initializing...");
  // initialize the RF Chip
  cc1101.init();
  cc1101.reset();
  cc1101.setSyncWord(&syncWord, false);
  cc1101.setCarrierFreq(CFREQ_433);
  cc1101.disableAddressCheck();
  
  Serial.print("CC1101_PARTNUM "); //cc1101=0
  b=cc1101.readReg(CC1101_PARTNUM, CC1101_STATUS_REGISTER);
  Serial.println(b);
  b=cc1101.readReg(CC1101_VERSION, CC1101_STATUS_REGISTER);
  Serial.print("CC1101_VERSION "); //cc1101=4
  Serial.println(b);  
  Serial.print("CC1101_MARCSTATE ");
  Serial.println(cc1101.readReg(CC1101_MARCSTATE, CC1101_STATUS_REGISTER) & 0x1f);
  
  Serial.println("device initialized");
}

void send_data() {
 CCPACKET data;
  data.length=1;
  byte blinkCount=counter++;
  data.data[0]=blinkCount;
  Serial.print("CC1101_MARCSTATE ");
  Serial.println(cc1101.readReg(CC1101_MARCSTATE, CC1101_STATUS_REGISTER) & 0x1f);
  if(cc1101.sendData(data)){
    Serial.print("sent ok :)");
    blinker();
  }else{
    Serial.print("sent failed :(");
    blinker();
    blinker();
  }   
}

void loop()
{
  send_data();
  Serial.println("loop done"); 
  delay(1000);
}
#include "EEPROM.h"
#include "cc1101.h"


#define LEDOUTPUT 7

// The connection to the hardware chip CC1101 the RF Chip
CC1101 cc1101;

byte b;
byte syncWord = 199; 

// a flag that a wireless packet has been received 
boolean packetAvailable = false;         

void blinker(){
      digitalWrite(LEDOUTPUT, HIGH);
      delay(100);
      digitalWrite(LEDOUTPUT, LOW);
      delay(100);
}

/**
* Handle interrupt from CC1101 (INT0)
*/
void cc1101signalsInterrupt(void){
  // set the flag that a package is available
  packetAvailable = true;
}

void setup()
{
  Serial.begin(38400);
  Serial.println("start");

  // setup the blinker output
  pinMode(LEDOUTPUT, OUTPUT);
  digitalWrite(LEDOUTPUT, LOW);

  // blink once to signal the setup
  blinker();
  //cc1101.reset();
  // initialize the RF Chip
  cc1101.init();
  cc1101.reset();
  cc1101.setSyncWord(&syncWord, false);
  cc1101.setCarrierFreq(CFREQ_433);
  cc1101.disableAddressCheck();
  
   Serial.print("CC1101_PARTNUM ");
  b=cc1101.readReg(CC1101_PARTNUM, CC1101_STATUS_REGISTER);
  Serial.println(b);
  b=cc1101.readReg(CC1101_VERSION, CC1101_STATUS_REGISTER);
  Serial.print("CC1101_VERSION ");
  Serial.println(b);  
  Serial.print("CC1101_MARCSTATE ");
  Serial.println(cc1101.readReg(CC1101_MARCSTATE, CC1101_STATUS_REGISTER)& 0x1f);

  attachInterrupt(0, cc1101signalsInterrupt, FALLING);
  Serial.println("device initialized");

  Serial.println("setup done");
}

void loop()
{
  if(packetAvailable){
    Serial.print("packet received");
    // Disable wireless reception interrupt
    detachInterrupt(0);

    // clear the flag
    packetAvailable = false;
    
    CCPACKET packet;
   
    if(cc1101.receiveData(&packet) > 0){
      if(!packet.crc_ok) {
        Serial.println("crc not ok");
      }
      if(packet.crc_ok && packet.length > 0){
        Serial.print("packet: len");
        Serial.print(packet.length);
        Serial.print(" data0: ");
        Serial.println(packet.data[0]);
      }
    }
    
    // Enable wireless reception interrupt
    attachInterrupt(0, cc1101signalsInterrupt, FALLING);
  }
}

A noter, les fréquences ci dessous marchent aussi :

cc1101.setCarrierFreq(CFREQ_868);
ou
cc1101.setCarrierFreq(CFREQ_915);