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.
main.cpp
- Committer:
- libv2001
- Date:
- 2017-02-12
- Revision:
- 0:0545bc9f81e0
File content as of revision 0:0545bc9f81e0:
#include "mbed.h" #include "rtos.h" #include "xbee.h" #define nullptr 0 DigitalOut led1(LED1); Serial pc(USBTX, USBRX); DigitalIn * btn; I2C * acc; Serial *xbee; DigitalOut *xbeeRst; Mutex xbeeMutex; int ReadButton(char*); int ReadAccelerometer(char*); const uint8_t DEVICE_COUNT = 2; int (* readFunctions[DEVICE_COUNT]) (char *) = {&ReadButton, &ReadAccelerometer}; const int HARDWARE_RESET_SIGNAL = 0x10; const int JOINED_NETWORK_SIGNAL = 0x20; const int TICKER_SIGNAL = 0x40; const int RESPONSE_SIGNAL = 0x80; Thread * XBeeConsumer; Thread * XBeeProducer; Ticker timer; int responseStatus; /*******************************************************/ /**********************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 pauseTime; int btnPin; int accSdaPin; int accSclPin; int xbeeTxPin; int xbeeRxPin; int xbeeRstPin; char key[10]; LocalFileSystem local("local"); void ReadConfig(){ FILE * f = fopen("/local/rooter.cfg", "r"); fscanf(f,"%s %x", key, &panID); pc.printf("Lecture de la config %s : %04x\r\n", key, panID); fscanf(f,"%s %d", key, &pauseTime); pc.printf("Lecture de la config %s : %d\r\n", key, pauseTime); fscanf(f,"%s %d", key, &btnPin); pc.printf("Lecture de la config %s : %d\r\n", key, btnPin); fscanf(f,"%s %d %d", key, &accSdaPin, &accSclPin); pc.printf("Lecture de la config %s : %d %d\r\n", key, accSdaPin, accSclPin); 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); fclose(f); } /*******************************************************/ /**********************XBEE SEND************************/ /*******************************************************/ char frameID = 0; inline char GetFrameID(){ ++frameID; if (frameID == 0){ frameID = 1; } return frameID; } const char coordinator64bit[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const char coordinator16bit[2] = {0xff, 0xfe}; 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]); wait_us(25); } } void XBeeSentTransmitCommand(char * data, int dataLength){ char buffer[128]; buffer[START_IDX] = START; buffer[LENGTH_MSB_IDX] = (dataLength + TRANSMIT_MIN_SIZE) >> 8; buffer[LENGTH_LSB_IDX] = (dataLength + TRANSMIT_MIN_SIZE) & 0xff; buffer[API_ID_IDX] = API_ID_TRANSMIT; buffer[FRAME_ID_IDX] = GetFrameID(); memcpy(&buffer[TRANSMIT_64BIT_MSB_IDX], coordinator64bit, ADDR_64BIT_SIZE); memcpy(&buffer[TRANSMIT_16BIT_MSB_IDX], coordinator16bit, ADDR_16BIT_SIZE); buffer[TRANSMIT_BROADCAST_IDX] = TRANSMIT_DEFAULT_BROADCAST; buffer[TRANSMIT_OPT_IDX] = TRANSMIT_DEFAULT_OPT; memcpy(&buffer[TRANSMIT_DATA_IDX], data, dataLength); SetCheckSum(buffer); while(true) { XBeeSend(buffer, dataLength + TRANSMIT_MIN_SIZE + FRAME_MIN_SIZE); Thread::signal_wait(RESPONSE_SIGNAL); switch (responseStatus){ case TRANSMIT_STATUS_OK: return; default: pc.printf("This Transit error occured : %02x\r\n", responseStatus); break; } } } 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 HandleXbeeTransmitStatus(char * cmd){ switch(cmd[TRANSMIT_STATUS_DELIVERY_STATUS_IDX]){ case TRANSMIT_STATUS_OK: responseStatus = cmd[TRANSMIT_STATUS_DELIVERY_STATUS_IDX]; XBeeProducer->signal_set(RESPONSE_SIGNAL); break; default: pc.printf("Unhandled transmit status received : %02x\r\n", cmd[TRANSMIT_STATUS_DELIVERY_STATUS_IDX]); } } 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_JOINED_NETWORK: XBeeProducer->signal_set(JOINED_NETWORK_SIGNAL); break; case MODEM_STATUS_DISASSOCIATED: XBeeProducer->signal_clr(JOINED_NETWORK_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; case API_ID_TRANSMIT_STATUS: HandleXbeeTransmitStatus(cmd); break; default: pc.printf("Unhandle XBee Command received : %02x\r\n", cmd[API_ID_IDX]); } } /*******************************************************/ /************************INIT***************************/ /*******************************************************/ bool InitAcc(){ char cmd[2]; char data[1]; // Lecture du registre WHO_AM_I (0x2a) cmd[0] = 0x0d; acc->write(0x1d<<1, cmd, 1, true); acc->read(0x1d<<1, data, 1); if (data[0] != 0x2a){ return false; } //Activation de l'accéléromètre cmd[0] = 0x2a; // CTRL_REG1 cmd[1] = 0x01; // Active = 1 acc->write(0x1d<<1,cmd,2,false); return true; } bool InitXBee(){ xbeeRst->write(0); wait(0.4); xbeeRst->write(1); Thread::signal_wait(HARDWARE_RESET_SIGNAL); XBeeSendATID(); XBeeSendATWR(); XBeeSendATAC(); Thread::signal_wait(JOINED_NETWORK_SIGNAL); pc.printf("XBee configured\r\n"); return true; } /*******************************************************/ /************************READ***************************/ /*******************************************************/ int ReadButton(char* buffer){ buffer[0] = 'B'; buffer[1] = 'T'; buffer[2] = 'N'; buffer[3] = (*btn); // 0x01 | 0x00 return 4; } int ReadAccelerometer(char* buffer){ const char deviceAddr = 0x1d<<1; char temp[1]; temp[0] = 0x01; // Adresse de OUT_X_MSB buffer[0] = 'A'; buffer[1] = 'C'; buffer[2] = 'C'; // Lecture des données X, Y et Z acc->write(deviceAddr, temp, 1, true); acc->read(deviceAddr, &buffer[3], 6); SetCheckSum(buffer); //Number of bytes to send return 9; } void ReadDevices(){ int count; char buffer[64]; for ( int i = 0; i < DEVICE_COUNT; ++i){ count = readFunctions[i](buffer); XBeeSentTransmitCommand(buffer, count); } } 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(){ //Initilisation if (!InitAcc()){ pc.printf("Connection problem with the ACC\r\n"); return false; } 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, pauseTime); while(true){ Thread::signal_wait(TICKER_SIGNAL); ReadDevices(); } } int main() { // Lecture de la configuration. ReadConfig(); //Créer les interfaces de communication des capteurs avec les données de la config. DigitalIn mainBtn(GetPinName(btnPin)); I2C mainAcc(GetPinName(accSdaPin), GetPinName(accSclPin)); Serial mainXbee(GetPinName(xbeeTxPin), GetPinName(xbeeRxPin)); DigitalOut mainXbeeRst(GetPinName(xbeeRstPin)); //Rendre les interfaces de communication globaux. btn = &mainBtn; acc = &mainAcc; 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); }