ilpaso 0 Posted November 18, 2014 Share Posted November 18, 2014 Hello everyone! I meet a problem using Air Boosterpack on launchpad MSP430F5529. I'm trying to make a small sensor network, a star network. 1 gateway and 2 sensors. The gateway sends a SYNC command to broadcast address. Each sensor listens for a random time if someone is trasmitting, if not it sends a RTS (Request To Send) command to gateway. The gateway sends back a CTS (Clear To Send). Once the sensor receives the CTS it will send back the data to the gateway. Before each Rx or Tx operation I've put a "while(Radio.busy())" as written in all examples. Very often gateway or sensor freezes after sending the packet and never exit from the "while(Radio.busy())" cycle. Can anyone help me with this issue? Thank you Attached here there are the gateway and sensor firmware. Please find the string "//IT FREEZES HERE!!!!" in order to see where the code is blocked. SENSOR: #include <SPI.h> #include <AIR430BoostETSI.h> // ----------------------------------------------------------------------------- /** * Defines, enumerations, and structure definitions */ #define ADDRESS_LOCAL 0x04 #define ADDRESS_REMOTE 0x02 // identify a set of type of data received/send (command in cordata struct) #define SYNC 1 #define CTS 2 #define RTS 3 #define SET 4 #define DATA 5 #define ACK 7 #define RLED P1_0 #define GLED P4_7 /** * sPacket - packet format. */ struct sPacket { uint8_t from; // Local node address that message originated from uint8_t message[59]; // Local node message [MAX. 59 bytes] }; // ----------------------------------------------------------------------------- /** * Global data */ struct sPacket rxPacket, txPacket; int timeout = 300; void setup() { startled(); // Setup serial for debug printing. Serial.begin(115200); Serial.print("SENSOR, address:"); Serial.println(ADDRESS_LOCAL); // The radio library uses the SPI library internally, this call initializes // SPI/CSn and GDO0 lines. Also setup initial address, channel, and TX power. Radio.begin(ADDRESS_LOCAL, CHANNEL_1, POWER_MAX); } void loop() { blinkled(GLED, 1, 50); ///WAIT SYNC rxPacket.from=0; // Local node address that message originated from memset(rxPacket.message,0,sizeof(rxPacket.message)); while(Radio.busy()){ Serial.println("BUSY RX SYNC^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); delay(5); } if(Radio.receiverOn((unsigned char*)&rxPacket, sizeof(rxPacket), timeout) > 0) { if(Radio.getCrcBit()!=1) { return; } } if (rxPacket.message[0] != SYNC) { Serial.println("NO SYNC"); return; } Serial.println("SYNC ARRIVED"); //CARRIER SENSE rxPacket.from=0; // Local node address that message originated from memset(rxPacket.message,0,sizeof(rxPacket.message)); while(Radio.busy()){ Serial.println("BUSY CARIER SENSE^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); delay(5); } if(Radio.receiverOn((unsigned char*)&rxPacket, sizeof(rxPacket), 100+random(timeout)) > 0) { Serial.println("CARRIER BUSY ********************************************"); return; } Serial.println("CARRIER FREE"); ///RTS delay(20); //attesa per dare il tempo al gateway di andare in rx txPacket.from = ADDRESS_LOCAL; memset(txPacket.message, 0, sizeof(txPacket.message)); txPacket.message [0] = 3; txPacket.message [1] = 1; txPacket.message [2] = 1; txPacket.message [3] = 1; Radio.transmit(ADDRESS_BROADCAST, (unsigned char*)&txPacket, sizeof(txPacket)); Serial.println("SENT RTS"); ///WAIT CTS rxPacket.from=0; // Local node address that message originated from memset(rxPacket.message,0,sizeof(rxPacket.message)); delay(80); while(Radio.busy()){ Serial.println("BUSY RX CTS^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); //IT FREEZES HERE!!!! delay(5); } if(Radio.receiverOn((unsigned char*)&rxPacket, sizeof(rxPacket), timeout) > 0) { if(Radio.getCrcBit()!=1) { Serial.println("NO CTS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); return; } } if (rxPacket.message[0] == CTS) { Serial.println("CTS ARRIVED"); Serial.println(""); blinkled(RLED, 1, 50); } else Serial.println("ERROR RECEIVING CTS"); delay(300); } void blinkled(uint8_t led, uint8_t time, uint8_t delayTime){ for(int i=0; i<time; i++){ digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) delay(delayTime); digitalWrite(led, LOW); // turn the LED off by making the voltage LOW delay(delayTime); } } void startled(){ pinMode(RLED, OUTPUT); pinMode(GLED, OUTPUT); } GATEWAY: #include <SPI.h> #include <AIR430BoostETSI.h> // ----------------------------------------------------------------------------- /** * Defines, enumerations, and structure definitions */ #define ADDRESS_LOCAL 0x02 // identify a set of type of data received/send (command in cordata struct) #define SYNC 1 #define CTS 2 #define RTS 3 #define SET 4 #define DATA 5 #define RLED P1_0 #define GLED P4_7 /** * sPacket - packet format. */ struct sPacket { uint8_t from; // Local node address that message originated from uint8_t message[59]; // Local node message [MAX. 59 bytes] }; // ----------------------------------------------------------------------------- /** * Global data */ struct sPacket rxPacket, txPacket; int timeout = 300; void setup() { startled(); // Setup serial for debug printing. Serial.begin(115200); Serial.print("GATEWAY, address:"); Serial.println(ADDRESS_LOCAL); // The radio library uses the SPI library internally, this call initializes // SPI/CSn and GDO0 lines. Also setup initial address, channel, and TX power. Radio.begin(ADDRESS_LOCAL, CHANNEL_1, POWER_MAX); } void loop() { blinkled(GLED, 1, 50); ///SEND SYNC txPacket.from = ADDRESS_LOCAL; memset(txPacket.message, 0, sizeof(txPacket.message)); txPacket.message [0] = SYNC; txPacket.message [1] = 1; txPacket.message [2] = 1; txPacket.message [3] = 1; while(Radio.busy()){ Serial.println("BUSY TX SYNC^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); delay(5); } Radio.transmit(ADDRESS_BROADCAST, (unsigned char*)&txPacket, sizeof(txPacket)); Serial.println("SYNC SENT"); delay(40); ///WAIT RTS rxPacket.from=0; // Local node address that message originated from memset(rxPacket.message,0,sizeof(rxPacket.message)); while(Radio.busy()){ Serial.println("BUSY RX RTS^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); //IT FREEZES HERE!!!! delay(5); } if(Radio.receiverOn((unsigned char*)&rxPacket, sizeof(rxPacket), timeout) > 0) { if(Radio.getCrcBit()!=1) { return; } } if (rxPacket.message[0] != RTS) { Serial.println("NO RTS"); return; } Serial.print("RTS ARRIVED from: "); Serial.println(rxPacket.from); ///SEND CTS delay(20); //wait txPacket.from = ADDRESS_LOCAL; memset(txPacket.message, 0, sizeof(txPacket.message)); txPacket.message [0] = CTS; txPacket.message [1] = 1; txPacket.message [2] = 1; txPacket.message [3] = 1; while(Radio.busy()){ Serial.println("BUSY TX CTS^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); delay(5); } Radio.transmit(rxPacket.from, (unsigned char*)&txPacket, sizeof(txPacket)); Serial.println("CTS SENT"); Serial.println(""); delay(100); } void blinkled(uint8_t led, uint8_t time, uint8_t delayTime){ for(int i=0; i<time; i++){ digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) delay(delayTime); digitalWrite(led, LOW); // turn the LED off by making the voltage LOW delay(delayTime); } } void startled(){ pinMode(RLED, OUTPUT); pinMode(GLED, OUTPUT); } Quote Link to post Share on other sites
energia 485 Posted November 19, 2014 Share Posted November 19, 2014 Try increasing the timeout to 1000. I recently discovered an issue with the timeout values being lower than 1000. Attached is the ETSI version of the library that fixes quite a few other things. Give that a try and let me know if it solves the lockup you are seeing. Place it in <Energia application directory>/hardware/msp430/libraries/. You might want to move the original out of the way and back it up before copying the new one. AIR430BoostEuropeETSI.zip Quote Link to post Share on other sites
ilpaso 0 Posted November 19, 2014 Author Share Posted November 19, 2014 Hi energia, thank you for your reply. Sorry but I forgot to write the Energia release: 0101E0013 with AIR430BoostEuropeETSI library downloaded from github: https://github.com/energia/Energia/commit/55cbbdb792fd092813c5b79a610690f52c12c5d1. I think this is the library release you attached in the post. I'll try this evening to increase the timeout to 1000. I've tested the code with a delay(500) (the last delay in the loop cycle) and it works a bit better. I've seen the function "boolean A110x2500Radio::busy()" in the library. It tests gDataTransmitting variable. Is this variable linked to interrupt at line GDO0? The signal raise up and falls down but interrupt doesn't see this change. Is this right? Thank you Quote Link to post Share on other sites
ilpaso 0 Posted November 20, 2014 Author Share Posted November 20, 2014 Increasing the timeout the module works better but the problem is not solved. Quote Link to post Share on other sites
zeke 693 Posted November 20, 2014 Share Posted November 20, 2014 You could (or should) put in a failsafe timer to kick out of that while loop. Something like this: FailSafeTimer = 0; while(Radio.busy() || FailSafeTimer >= 10) { Serial.println("BUSY TX CTS^^^^^^^^^^^^^^^^^^^^^"); FailSafeTimer++; delay(5); } That will kick the loop out after (10*5)=50 seconds and that should keep you from pulling your hair out while developing your code. I don't know the Radio.busy() routine but my intuition says that it isn't working as you expect. Quote Link to post Share on other sites
ilpaso 0 Posted November 20, 2014 Author Share Posted November 20, 2014 Hi zeke, thank you for your nice workaround and moral support. I'll try it but I think you've confused: - || and && ; - >= 10 and <=10; - the delay is (10*5)=50 milliSeconds. does not matter In the WirelessControl example for AIR430Boost ETSI library there is this note: /** * The radio transmitter and receiver cannot be operated at the same time. * Wait until transmit completes before turning on the receiver. Please note * that the radio is considered busy when it is transmitting. * * WARNING: If busy is not checked between two successive radio operations * receiverOn/transmit, the radio may not perform the specified task. The * radio must be complete with the transmission before it can begin the next */ This is the infamous routine: boolean A110x2500Radio::busy() { if (gDataTransmitting) { return true; } return false; } and this routine changes the gDataTransmitting variable void A110x2500Radio::gdo0Isr() { // Note: It is assumed that interrupts are disabled. // The GDO0 ISR will only look for the EOP edge. Therefore, if the radio // is not transmitting the EOP, it must be receiving an EOP signal. if (gDataTransmitting) { /** * Note: GDO0 is issued prior to the transmitter being completely * finished. The state machine will remain in TX_END until transmission * completes. The following waits for TX_END to correct the hardware * behavior. */ while (CC1101GetMarcState(&gPhyInfo.cc1101) == eCC1101MarcStateTx_end); gDataTransmitting = false; } else { gDataReceived = true; readDataStream(); } // Always go back to sleep. sleep(); } I do not know how the module works at a lower level. I hoped that the library would work because it was initially released by Anaren. Maybe something I'm wrong. Bye Quote Link to post Share on other sites
ilpaso 0 Posted November 20, 2014 Author Share Posted November 20, 2014 I've tried the workaround but it does't work. It kicks the loop out after 50 milliseconds but returns in the loop the next attempt. Bye Quote Link to post Share on other sites
zeke 693 Posted November 20, 2014 Share Posted November 20, 2014 Yes, the code will drop back into that while loop because of the main loop() is continuously repeating. It's normal. According to that note: /** * The radio transmitter and receiver cannot be operated at the same time. * Wait until transmit completes before turning on the receiver. Please note * that the radio is considered busy when it is transmitting. * * WARNING: If busy is not checked between two successive radio operations * receiverOn/transmit, the radio may not perform the specified task. The * radio must be complete with the transmission before it can begin the next */ I would guess that the transmitter is stuck on. That sounds like a bad situation and it doesn't seem likely to me. Here are some questions that I would try to answer if I had the stuff in front of me: What is the normal transmit time of a packet? Are there any signals that I can probe with an oscilloscope and watch? Is there a pin that tells me when the transmitter is active? Is the transmitter stuck on? Does the busy flag ever clear? Is it stuck in the busy state all the time? Can I force it to not transmit? Is there some sample code that I could try out to see how it works when it's working properly? Can I mimic that code? What am I doing different than that code? What are the maximum sizes of my data structures? Am I exceeding the maximum buffer sizes anywhere in my code? Have I exceeded the memory limitations of my processor? Have I passed my buffers by reference or on the stack? Have I corrupted the stack by overflowing a variable during a function call? Quote Link to post Share on other sites
Lgbeno 189 Posted November 21, 2014 Share Posted November 21, 2014 Make sure to check the state of GDO0 as well to make sure that it is toggling to actually trigger the isr. Could the CPU be missing it? Quote Link to post Share on other sites
ilpaso 0 Posted November 21, 2014 Author Share Posted November 21, 2014 Gdo0 changes the logic state perfectly. I think the cpu doesn't see the edge on falling down gdo0 line. maybe could be an spi problem. I've no idea how solve the problem. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.