This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2500: Communication between MSP430F5529 and Arduino Mega2560 using CC2500 - Synchronization Problem

Part Number: CC2500


Tool/software:

Hello everyone im currently working on a program to communicate between msp430 and arduino right now im facing a problem in synchronization and i need to sync the communication between the arduino and msp.

When i try to do switch from tx to rx mode in the arduino and switch from rx to tx in the msp430 i cant seem to communicate, i think this is due to synchronization problem because when i try to do only one of the modes (RX or TX) and not switch between the modes the arduino and the mps430 can communicate i think this is due to the fact the arduino is being used with pooling so if the sync word fails it will repeat either way and fire the GDO interrupt and the msp will eventually read the buffer (in case of arduino (TX) and msp (RX)).

Here i have the codes for both to shorten the codes i will only include the more important parts:

ARDUINO

  /* ARDUINO CODE - NOTE: the wakeUp routine dosent do nothing */
 while (1)
 { 
  digitalWrite(4, HIGH);
  sendPacketINT(buffer_tx, 5);
  delay(500);

  attachInterrupt(2, wakeUp, FALLING);

  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); 
  detachInterrupt(2);

  digitalWrite(4, LOW);

  SendStrobe(CC2500_SIDLE);
  SendStrobe(CC2500_SFTX);
  SendStrobe(CC2500_SFRX);
  
  // RX
  SendStrobe(CC2500_SRX);
  delay(500);

  attachInterrupt(2, wakeUp, FALLING);

  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); 
  detachInterrupt(2);

  //while(digitalRead(GDO0));

  listenForPacket(buffer_rx, 5);

  if (buffer_rx[4] == length)
  {
    digitalWrite(4, HIGH);
  }
}


MSP

// GDO init: P2.0 - reg 0x02 | val 0x06
  P2DIR &= ~BIT0;       // input
  P2REN |= BIT0;        // enable pull up/pull down resistor
  P2OUT |= BIT0;        // use as pull up resistor
  P2IES |= BIT0;        // interrupt edge (H -> L)
  P2IFG &= ~BIT0;
  P2IE &= ~BIT0;

  while (1)
  {
    // LER
    
    P2IFG &= ~BIT0;
    P2IE |= BIT0;

    sendStrobe(CC2500_SRX);

    __bis_SR_register(GIE + LPM0_bits);

    for (int i = 0; i < 5; i++)
    {
      buffer_rx[i] = CC2500_read_register(CC2500_RXFIFO);
    }
    
    if (length == buffer_rx[4])
    {
      P1OUT |= BIT0;
      received = 1;
    }
    
    sendStrobe(CC2500_SIDLE);

    // Flush RX FIFO
    sendStrobe(CC2500_SFRX);
    
    for (int i = 0; i < 5; i++)
    {
      write(*(point_tx + i),CC2500_TXFIFO);
    }
    
    // Transmitter mode
    sendStrobe(CC2500_STX);
    __delay_cycles(500000); // 500 ms

    // reativar interrupt gdo e escrever tudo no TXFIFO
    P2IFG &= ~BIT0;
    P2IE |= BIT0;

    __bis_SR_register(GIE + LPM0_bits);

    // go back to rx mode and flush TX FIFO

    sendStrobe(CC2500_SIDLE);
    //__delay_cycles(100);


    sendStrobe(CC2500_SFTX);

    P1OUT &= ~BIT0;


Block diagram of the system:


The goal is for the arduino to send a message and the msp430 respond with another.

I have tried using delays on the arduino, but found out pretty quick that its not efficient maybe use a timer for both?

Really would appreciate help with this, thank you for your time!

  • Hello,

    Can you please provide a block diagram of your system?

    If I understand correctly, you have two systems, each with a controller + CC2500 like so:

    1. MSP + CC2500 (for simplification, I'll call this MSP)
    2. Arduino + CC2500 (for simplification, I'll call this Ard)

    I would recommend that you test delays when transitioning from RX to TX, and also to ensure the RX time of the other device remains on for a bit longer.
    For example, a sequence could look like this:

    1. MSP switches from TX to RX at time t_rxStart, and stays this way for t_rxStay
    2. Ard switches from RX to TX at time t_txStart, where t_rxStart + t_txDelta < t_txStart < t_rxStart + t_rxStay

    I'd recommend adding GPIO toggles on both MSP and Ard to indicate where each TX and RX is starting (i.e. 2 GPIOs on each controller, one for TX active and one for RX active).

    Thanks,
    Toby

  • Hello Toby,

    I have updated the post with the block diagram to make it more visually understandable!

    In follow up to your suggestion i have a question, right now the distance between the modules is short but if the distance would increase these delays would most likely have to be adjusted right?

    Im gonna try your suggestion, going to try to find out when the TX and RX modes start and go from there.

    I'll get back at you, thank you very much for your help and time!

  • Hello Toby i am now able of receiving and sending between both microcontrollers but for some reason the msp gets stuck in receiver and cant receive anymore and i need to reset the arduino for it to start receiving again any clues?

    Here is the codes updated:

    Arduino

    void loop() 
    {
      delay(500);
      
      digitalWrite(5, HIGH);
    
      digitalWrite(4, HIGH);
      sendPacketINT(buffer_tx, 5);
    
      attachInterrupt(2, wakeUp, FALLING);
    
      LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); 
      detachInterrupt(2);
    
      digitalWrite(4, LOW);
    
      SendStrobe(CC2500_SIDLE);
      SendStrobe(CC2500_SFTX);
      
    
      // RX
      SendStrobe(CC2500_SRX);
      digitalWrite(5, LOW);
    
      attachInterrupt(2, wakeUp, FALLING);
    
      LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); 
      detachInterrupt(2);
    
      while(digitalRead(GDO0));
    
      listenForPacket(buffer_rx, 5);
    
      if (buffer_rx[4] == length)
      {
        digitalWrite(4, HIGH);
      }
      
      SendStrobe(CC2500_SFRX);
      delay(2000); // consegui 5 mensagens seguidas
    }


    MSP:

      while (1)
      {
        // LER
        P2IFG &= ~BIT0;
        P2IE |= BIT0;
        
        sendStrobe(CC2500_SRX);
        __delay_cycles(1000);
        P1OUT &= ~BIT5;
    
        __bis_SR_register(GIE + LPM0_bits);
    
        P1OUT |= BIT5;
    
        for (int i = 0; i < 5; i++)
        {
          buffer_rx[i] = CC2500_read_register(CC2500_RXFIFO);
        }
    
        if (length == buffer_rx[4])
        {
          P1OUT |= BIT0;
          received = 1;
        }
    
        sendStrobe(CC2500_SIDLE);
    
        // Flush RX FIFO
        sendStrobe(CC2500_SFRX);
        
        for (int i = 0; i < 5; i++)
        {
          write(*(point_tx + i),CC2500_TXFIFO);
        }
        
        __delay_cycles(500000); // 500 ms
        // Transmitter mode
        sendStrobe(CC2500_STX);
        P1OUT &= ~BIT5;
    
        // reativar interrupt gdo e escrever tudo no TXFIFO
        P2IFG &= ~BIT0;
        P2IE |= BIT0;
    
        __bis_SR_register(GIE + LPM0_bits);
    
        // go back to rx mode and flush TX FIFO
    
        sendStrobe(CC2500_SIDLE);
    
        sendStrobe(CC2500_SFTX);
        __delay_cycles(1000);
    
        P1OUT &= ~BIT0;


    Thank you for your time and help!

  • Hello José,

    Glad to hear things are progressing on your system! And thanks for sharing the block diagram.

    For the new issue you observe, is it happening on known intervals? E.g. Does it always happen after X packets? or X time?

    the msp gets stuck in receiver and cant receive anymore and i need to reset the arduino for it to start receiving again

    This is a good clue here. It seems what could be happening, is that MSP is stuck in receive because it started that particular RX not in time to receive the Ard TX. So then, when you reset the Ard TX, the MSP starts receiving packet again, since the MSP is now for sure in RX in time to receive the Ard TX.

    I'd recommend playing around with the timing intervals, since there could be some additional timing variation which needs to be accounted for.

    In follow up to your suggestion i have a question, right now the distance between the modules is short but if the distance would increase these delays would most likely have to be adjusted right?

    Yes, this is good intuition. The distance typically has impact on the timings due to reduced TX power (inverse square). More distance also introduces more potential sources of noise, which impacts over-the-air signals. Generally it's recommended to do range testing to verify working distance.

    Thanks,
    Toby

  • Hello Toby i ended up switching CC2500's on the msp side and it started working... the GDO pin in the msp side was broken it was indeed a hardware problem!

    Thank you so much Toby for the help!