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
Diff: main.cpp
- Revision:
- 0:671a7b7e4673
- Child:
- 2:ff0b74e5e62c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Feb 12 16:07:11 2017 +0000 @@ -0,0 +1,365 @@ +#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); +}