Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed-rtos mbed EthernetInterface
main.cpp
- Committer:
- libv2001
- Date:
- 2017-02-12
- Revision:
- 0:671a7b7e4673
- Child:
- 2:ff0b74e5e62c
File content as of revision 0:671a7b7e4673:
#include "mbed.h" #include "rtos.h" #include "xbee.h" #define nullptr 0 DigitalOut myled(LED1); Serial pc(USBTX, USBRX); Serial *xbee; DigitalOut *xbeeRst; const int HARDWARE_RESET_SIGNAL = 0x10; const int COORDINATOR_STARTED_SIGNAL = 0x20; const int TICKER_SIGNAL = 0x40; const int RESPONSE_SIGNAL = 0x80; Thread * XBeeConsumer; Thread * XBeeProducer; Thread * EventConsumer; Ticker timer; int responseStatus; char * BTN_ID = "BTN"; char * ACC_ID = "ACC"; struct ButtonEvent{ char id[3]; bool state; }; struct AccelerometerEvent { char id[3]; char x[2], y[2], z[2]; }; MemoryPool<ButtonEvent, 32> btnPool; MemoryPool<AccelerometerEvent, 32> accPool; Queue<void, 64> event; struct Rooter{ long long int addr64; short addr16; bool operator==(const Rooter & rhs){ return addr64 == rhs.addr64 && addr16 == rhs.addr16; } }; #define ROOTER_MAX 2 Rooter rooters[ROOTER_MAX]; int rooterCount = 0; /*******************************************************/ /**********************UTILITIES************************/ /*******************************************************/ PinName GetPinName(const int p){ switch(p){ case 5: return p5; case 6: return p6; case 7: return p7; case 8: return p8; case 9: return p9; case 10: return p10; case 11: return p11; case 12: return p12; case 13: return p13; case 14: return p14; case 15: return p15; case 16: return p16; case 17: return p17; case 18: return p18; case 19: return p19; case 20: return p20; case 21: return p21; case 22: return p22; case 23: return p23; case 24: return p24; case 25: return p25; case 26: return p26; case 27: return p27; case 28: return p28; case 29: return p29; case 30: return p30; } pc.printf("Numero de pin invalid"); return NC; } /*******************************************************/ /***********************CONFIG**************************/ /*******************************************************/ int panID; int xbeeTxPin; int xbeeRxPin; int xbeeRstPin; char server[16]; char key[10]; LocalFileSystem local("local"); void ReadConfig(){ memset(server, 0x00, 16); FILE * f = fopen("/local/coord.cfg", "r"); fscanf(f,"%s %x", key, &panID); pc.printf("Config started\r\n"); pc.printf("Lecture de la config %s : %04x\r\n", key, panID); fscanf(f,"%s %d %d %d", key, &xbeeTxPin, &xbeeRxPin, &xbeeRstPin); pc.printf("Lecture de la config %s : %d %d %d\r\n", key, xbeeTxPin, xbeeRxPin, xbeeRstPin); fscanf(f,"%s %s", key, server); pc.printf("Lecture de la config %s : %s\r\n", key, server); fclose(f); } /*******************************************************/ /**********************XBEE SEND************************/ /*******************************************************/ char frameID = 0; inline char GetFrameID(){ ++frameID; if (frameID == 0){ frameID = 1; } return frameID; } void SetCheckSum(char * buffer){ uint16_t length = GetFrameLength(buffer); char sum = 0; int max = length + 3; for(int i = 3; i < max; ++i){ sum += buffer[i]; } buffer[max] = 0xff - sum; } void XBeeSend(char * buffer, int count){ for ( int i = 0; i < count; ++i ){ xbee->putc(buffer[i]); } } void XBeeSendATCommand(bool queue, char * type, char * data, int dataLength){ char buffer[128]; buffer[START_IDX] = START; buffer[LENGTH_MSB_IDX] = (dataLength + AT_MIN_SIZE) >> 8; buffer[LENGTH_LSB_IDX] = (dataLength + AT_MIN_SIZE) & 0xff; buffer[API_ID_IDX] = queue ? API_ID_AT_CMD_QUEUE : API_ID_AT_CMD; buffer[FRAME_ID_IDX] = GetFrameID(); memcpy(&buffer[AT_CMD_ID_IDX], type, AT_CMD_ID_SIZE); memcpy(&buffer[AT_PARAM_IDX], data, dataLength); SetCheckSum(buffer); if (!ValidateCheckSum(buffer)){ pc.printf("CheckSum problem\r\n"); } while(true){ XBeeSend(buffer, dataLength + AT_MIN_SIZE + FRAME_MIN_SIZE); Thread::signal_wait(RESPONSE_SIGNAL); switch (responseStatus){ case AT_CMD_RSP_STATUS_OK: return; case AT_CMD_RSP_STATUS_ERROR: case AT_CMD_RSP_STATUS_INVALID_CMD: case AT_CMD_RSP_STATUS_INVALID_PARAM: case AT_CMD_RSP_STATUS_TX_FAILURE: default: pc.printf("This AT error occured : %02x\r\n", responseStatus); break; } } } inline void XBeeSendATID(){ char idBuf[8]; for (int i = 0; i < 8; ++i){ idBuf[i] = (panID >> (56 - 8 * i)) & 0xff; } XBeeSendATCommand(true, "ID", idBuf, 8); } inline void XBeeSendATWR(){ XBeeSendATCommand(true, "WR", nullptr, 0); } inline void XBeeSendATAC(){ XBeeSendATCommand(true, "AC", nullptr, 0); } /*******************************************************/ /**********************XBEE READ************************/ /*******************************************************/ void HandleBtnPacket(char* cmd){ ButtonEvent* evt = btnPool.alloc(); memcpy(evt->id, BTN_ID, 3); evt->state = cmd[RECEIVED_PACKET_DATA_IDX + 3] == 0x01; event.put((void*)evt); } void HandleAccPacket(char* cmd){ AccelerometerEvent* evt = accPool.alloc(); memcpy(evt->id, ACC_ID, 3); memcpy(evt->x, &cmd[RECEIVED_PACKET_DATA_IDX + 3], 2); memcpy(evt->y, &cmd[RECEIVED_PACKET_DATA_IDX + 5], 2); memcpy(evt->z, &cmd[RECEIVED_PACKET_DATA_IDX + 7], 2); event.put((void*)evt); } void HandleXbeeReceivedPacket(char * cmd){ if (cmd[RECEIVED_PACKET_DATA_IDX] == BTN_ID[0] && cmd[RECEIVED_PACKET_DATA_IDX + 1] == BTN_ID[1] && cmd[RECEIVED_PACKET_DATA_IDX + 2] == BTN_ID[2]){ HandleBtnPacket(cmd); } if (cmd[RECEIVED_PACKET_DATA_IDX] == ACC_ID[0] && cmd[RECEIVED_PACKET_DATA_IDX + 1] == ACC_ID[1] && cmd[RECEIVED_PACKET_DATA_IDX + 2] == ACC_ID[2]){ HandleAccPacket(cmd); } } void HandleXbeeModemStatus(char * cmd){ switch(cmd[MODEM_STATUS_STATUS_IDX]){ case MODEM_STATUS_HARDWARE_RST: XBeeProducer->signal_set(HARDWARE_RESET_SIGNAL); break; case MODEM_STATUS_COORDINATOR_STARTED: XBeeProducer->signal_set(COORDINATOR_STARTED_SIGNAL); break; default: pc.printf("Unhandled modem status received : %02x\r\n", cmd[MODEM_STATUS_STATUS_IDX]); break; } } void HandleXBeeATCommandResponse(char * cmd){ responseStatus = cmd[AT_CMD_RSP_STATUS_IDX]; XBeeProducer->signal_set(RESPONSE_SIGNAL); } void HandleXbeeReceivedCommand(char * cmd){ switch(cmd[API_ID_IDX]){ case API_ID_AT_CMD_RSP: HandleXBeeATCommandResponse(cmd); break; case API_ID_MODEM_STATUS: HandleXbeeModemStatus(cmd); break; default: pc.printf("Unhandle XBee Command received : %02x\r\n", cmd[API_ID_IDX]); } } /*******************************************************/ /************************INIT***************************/ /*******************************************************/ bool InitXBee(){ xbeeRst->write(0); wait(0.4); xbeeRst->write(1); Thread::signal_wait(HARDWARE_RESET_SIGNAL); XBeeSendATID(); XBeeSendATWR(); XBeeSendATAC(); Thread::signal_wait(COORDINATOR_STARTED_SIGNAL); pc.printf("XBee configured\r\n"); return true; } void ConsumerMain(){ char buffer[128]; while(true){ while(!xbee->readable()){ continue; } buffer[START_IDX] = xbee->getc(); if (buffer[START_IDX] != START){ pc.printf("Wrong start byte received : %02x\r\n", buffer[START_IDX]); continue; } buffer[LENGTH_MSB_IDX] = xbee->getc(); buffer[LENGTH_LSB_IDX] = xbee->getc(); int length = GetFrameLength(buffer); for (int i = 0; i <= length; ++i){ buffer[i + API_ID_IDX] = xbee->getc(); } if (!ValidateCheckSum(buffer)){ pc.printf("Bad CheckSum : %02x\r\n", buffer[length + FRAME_MIN_SIZE - 1]); continue; } HandleXbeeReceivedCommand(buffer); } } bool ProducerInit(){ if (!InitXBee()){ pc.printf("Connection problem with the XBee\r\n"); return false; } return true; } void Tick(){ XBeeProducer->signal_set(TICKER_SIGNAL); } void ProducerMain(const void*){ if (!ProducerInit()){ pc.printf("Initialization problem\r\n"); return; } timer.attach(&Tick, 1); while(true){ Thread::signal_wait(TICKER_SIGNAL); // Send Remote AT Command } } int main() { // Lecture de la configuration. ReadConfig(); //Créer les interfaces de communication des capteurs avec les données de la config. Serial mainXbee(GetPinName(xbeeTxPin), GetPinName(xbeeRxPin)); DigitalOut mainXbeeRst(GetPinName(xbeeRstPin)); //Rendre les interfaces de communication globaux. xbee = &mainXbee; xbeeRst = &mainXbeeRst; Thread consumer(ConsumerMain); XBeeConsumer = &consumer; Thread producer(ProducerMain); XBeeProducer = &producer; // Mettre la thread principale dans un état de waiting à l'infinie Thread::signal_wait(0x1); }