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.
Diff: main.cpp
- Revision:
- 0:0545bc9f81e0
diff -r 000000000000 -r 0545bc9f81e0 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Feb 12 16:06:13 2017 +0000 @@ -0,0 +1,442 @@ +#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); +}