[Firebug-cvs] mts400/apps/TestFireBoard .cvsignore,NONE,1.1 Makefile,NONE,1.1 fireboard.nc,NONE,1.1
Brought to you by:
doolin
From: <do...@us...> - 2003-11-26 18:38:48
|
Update of /cvsroot/firebug/mts400/apps/TestFireBoard In directory sc8-pr-cvs1:/tmp/cvs-serv31741/TestFireBoard Added Files: .cvsignore Makefile fireboard.nc fireboardM.nc Log Message: FireBoard with gps, light, temp, hum and pressure now works together. --- NEW FILE: .cvsignore --- build *~ --- NEW FILE: Makefile --- COMPONENT=fireboard SENSORBOARD=gps include ../Makelocal include $(TOSROOT)/apps/Makerules --- NEW FILE: fireboard.nc --- /* -*- Mode: C; c-basic-indent: 3; indent-tabs-mode: nil -*- */ includes sensorboard; configuration fireboard { } implementation { components Main, fireboardM, MicaWbSwitch, UARTGpsPacket, IntersemaPressure, SensirionHumidity, TaosPhoto, TimerC, LedsC; Main.StdControl -> fireboardM.StdControl; Main.StdControl -> TimerC.StdControl; Main.StdControl -> MicaWbSwitch.StdControl; fireboardM.Leds -> LedsC; fireboardM.GlobalTimer -> TimerC.Timer[unique("Timer")]; fireboardM.PowerSwitch -> MicaWbSwitch.Switch[0]; fireboardM.IOSwitch -> MicaWbSwitch.Switch[1]; fireboardM.GpsControl -> UARTGpsPacket; fireboardM.GpsSend -> UARTGpsPacket; fireboardM.GpsReceive -> UARTGpsPacket; fireboardM.GpsCmd -> UARTGpsPacket.GpsCmd; // Wiring for Sensirion humidity/temperature sensor fireboardM.TempHumControl -> SensirionHumidity; fireboardM.Humidity -> SensirionHumidity.Humidity; fireboardM.Temperature -> SensirionHumidity.Temperature; fireboardM.HumidityError -> SensirionHumidity.HumidityError; fireboardM.TemperatureError -> SensirionHumidity.TemperatureError; // Wiring for Intersema barometric pressure/temperature sensor fireboardM.IntersemaCal -> IntersemaPressure; fireboardM.PressureControl -> IntersemaPressure; fireboardM.IntersemaPressure -> IntersemaPressure.Pressure; fireboardM.IntersemaTemp -> IntersemaPressure.Temperature; fireboardM.TaosControl -> TaosPhoto; fireboardM.TaosCh0 -> TaosPhoto.ADC[0]; fireboardM.TaosCh1 -> TaosPhoto.ADC[1]; } --- NEW FILE: fireboardM.nc --- /* -*- Mode: C; c-basic-indent: 3; indent-tabs-mode: nil -*- */ module fireboardM { provides { interface StdControl; command void readGps(); command void stopGps(); } uses { interface Leds; interface Timer as GlobalTimer; interface StdControl as SwitchControl; interface Switch as PowerSwitch; interface Switch as IOSwitch; interface StdControl as GpsControl; interface I2CSwitchCmds as GpsCmd; interface BareSendMsg as GpsSend; interface ReceiveMsg as GpsReceive; interface SplitControl as TempHumControl; interface ADC as Humidity; interface ADC as Temperature; interface ADCError as HumidityError; interface ADCError as TemperatureError; //Intersema interface SplitControl as PressureControl; //interface StdControl as PressureControl; interface ADC as IntersemaTemp; interface ADC as IntersemaPressure; interface Calibration as IntersemaCal; interface SplitControl as TaosControl; interface ADC as TaosCh0; interface ADC as TaosCh1; } } implementation { #include "SODebug.h" #include "gps.h" /** 0 means GPS runs forever, 1 means it takes one reading * and powers down. * FIXME: The GPS sensor powers back up after it powers down, * this should not happen and is a problem. */ #define GPS_ONE_SHOT 1 //char state; char gps_state; char switch_state; char state1; uint16_t TaosData; enum {IDLE, BUSY, BUSY_0, BUSY_1, GET_SAMPLE_0, GET_SAMPLE_1, OPENSCK, OPENDATA, CLOSESCK, CLOSEDATA, POWEROFF, MAIN_SWITCH_ON, MAIN_SWITCH_OFF, WAIT_SWITCH_ON, WAIT_SWITCH_OFF, TIMER, GPS_DONE, SHT_DONE, HUMIDITY_DONE, PRESSURE_DONE, LIGHT_DONE}; uint16_t HumData; //Intersema variables uint16_t calibration[6]; uint16_t C1,C2,C3,C4,C5,C6; uint16_t PressureData; char count; command result_t StdControl.init() { init_debug(); state1 = IDLE; call Leds.init(); /** Control.init in GpsPacket.nc */ call GpsControl.init(); call TempHumControl.init(); call PressureControl.init(); return SUCCESS; } command result_t StdControl.start() { call Leds.redOn(); call HumidityError.enable(); //in case Sensirion doesn't respond call TemperatureError.enable(); // " /** Control.start in GpsPacket.nc, calls * SwitchControl.start and ByteControl.start() * Move those functions up here out of the GPS * driver, then abstract the sensorboard * component away. */ //call GpsControl.start(); call GlobalTimer.start(TIMER_REPEAT, 3000) ; return SUCCESS; } command result_t StdControl.stop() { call GlobalTimer.stop(); return SUCCESS; } command void stopGps() { if (call GpsCmd.PowerSwitch(GPS_POWER_OFF)) { SODbg(DBG_USR2, "gps_sht_baroM.stopGps.stop(): GPS sensor powered off. \n"); } state1 = GPS_DONE; } /** Ok, this function turns on the gps unit for reading, * which is turned of elsewhere when the read is finished. * If the read isn't finished, the function exits. */ command void readGps() { call Leds.greenToggle(); call GpsControl.start(); /* Implementation is in GpsPacket.nc */ if (call GpsCmd.PowerSwitch(GPS_POWER_ON)) { SODbg(DBG_USR2, "gps_sht_baroM.readGps(): GPS powered on\n"); } } event result_t GlobalTimer.fired() { switch (state1) { case BUSY: SODbg(DBG_USR2, "gps_sht_baroM.GlobalTimer.fired(), BUSY\n"); break; case IDLE: state1 = BUSY; call readGps(); break; case GPS_DONE: state1 = BUSY; call TempHumControl.start(); break; case SHT_DONE: state1 = BUSY; call PressureControl.start(); break; case PRESSURE_DONE: state1 = BUSY; call TaosControl.start(); break; case LIGHT_DONE: state1 = IDLE; break; default: break; } return SUCCESS; } event result_t PowerSwitch.getDone(char value) { return SUCCESS; } /** FIXME: Make sure we don't need the startDone, stopDone * calls. Where is this called from? */ event result_t PowerSwitch.setDone(bool local_result) { switch(switch_state) { case MAIN_SWITCH_ON: SODbg(DBG_USR2, "PowerSwitch.setDone() MAIN_SWITCH_ON\n"); switch_state = IDLE; /** GpsControl is wired to GpsPacket.nc */ //signal GpsControl.startDone(); break; case MAIN_SWITCH_OFF: SODbg(DBG_USR2, "PowerSwitch.setDone() MAIN_SWITCH_OFF\n"); switch_state = POWEROFF; /** GpsControl is wired to GpsPacket.nc */ //signal GpsControl.stopDone(); break; case WAIT_SWITCH_ON: SODbg(DBG_USR2, "PowerSwitch.setDone() WAIT_SWITCH_ON\n"); if (call PowerSwitch.set(MICAWB_GPS_POWER,1) == SUCCESS) { switch_state = MAIN_SWITCH_ON; } break; case WAIT_SWITCH_OFF: SODbg(DBG_USR2, "PowerSwitch.setDone() WAIT_SWITCH_OFF\n"); if (call PowerSwitch.set(MICAWB_GPS_POWER,0) == SUCCESS) { switch_state = MAIN_SWITCH_OFF; } default: break; } return SUCCESS; } event result_t PowerSwitch.setAllDone(bool local_result) { return SUCCESS; } event result_t IOSwitch.getDone(char value) { return SUCCESS; } event result_t IOSwitch.setAllDone(bool local_result) { return SUCCESS; } /** FIXME: Rewrite this with a switch/case. */ /** FIXME: I see no reason why we need I2C information this * high in the application. All this I2C bus info needs * to be shoved down a level, and wired from here to something * like turnSensorOn(), turnSensorOff(), etc. */ event result_t IOSwitch.setDone(bool local_result) { //SODbg(DBG_USR2, "gps_sht_baroM.IOSwitch.setDone(): state: %i \n", state); if (switch_state == OPENSCK) { //SCK line enabled SODbg(DBG_USR2, "gps_sht_baroM.IOSwitch.setDone(): SCK enabled \n"); switch_state = OPENDATA; return call IOSwitch.set(MICAWB_HUMIDITY_DATA,1); } else if (switch_state == OPENDATA) { //Data line enabled SODbg(DBG_USR2, "gps_sht_baroM.IOSwitch.setDone(): SDA enabled \n"); switch_state = TIMER; SODbg(DBG_USR2, "gps_sht_baroM.IOSwitch.setDone(): Timer Started, state: %i \n", switch_state); //call GPSTimer.start(TIMER_ONE_SHOT, 100); return SUCCESS; } else if (switch_state == CLOSESCK) { switch_state = CLOSEDATA; SODbg(DBG_USR2, "gps_sht_baroM.IOSwitch.setDone(): SCK disabled \n"); return call IOSwitch.set(MICAWB_HUMIDITY_DATA,0); } else if (switch_state == CLOSEDATA) { SODbg(DBG_USR2, "gps_sht_baroM.IOSwitch.setDone(): SDA disabled \n"); } return SUCCESS; } /** * Packet received from GPS - ASCII msg * 1st byte in pkt is number of ascii bytes * async used only for testing. * * FIXME: Why is the data returned? It's passed in. * It should be declared const. * * This function is called from GpsPacket.receiveTask(). */ event TOS_MsgPtr GpsReceive.receive(TOS_MsgPtr data) { uint8_t i; GPS_MsgPtr gps_data = (GPS_MsgPtr)data; call Leds.greenToggle(); for (i=0; i<=gps_data->data[0]; i++) { /** UARTPutChar is an SODebug function. * FIXME: Change this to use a char[]. */ UARTPutChar(gps_data->data[i]); } SODbg(DBG_USR2, "\n"); /** FIXME: Pulled the preprocessor define out, * code this up as a user defined variable that * is set when the gps unit is initialized. */ #if GPS_ONE_SHOT { /** Already written out one message. */ static uint16_t msg_count = 1; if (msg_count == 5) { call stopGps(); msg_count = 0; } msg_count++; } #endif return data; } event result_t GpsSend.sendDone(TOS_MsgPtr msg, result_t success) { SODbg(DBG_USR2, "GpsSend.sendDone(): state: %i \n", switch_state); return SUCCESS; } event result_t GpsCmd.SwitchesSet(uint8_t PowerState) { char tmp[] = {"Foo"}; //SODbg(DBG_USR2, "gps_sht_baro.GpsCmd.SwitchesSet(): PowerState: %i \n\n", PowerState); //SODbg(DBG_USR2, "gps_sht_baro.GpsCmd.SwitchesSet(): dummy string: %s \n", tmp); call Leds.yellowOn(); call Leds.redOff(); return SUCCESS; } /****************************************************************************** * Sensirion SHT11 humidity/temperature sensor * - Humidity data is 12 bit: * Linear calc (no temp correction) * fRH = -4.0 + 0.0405 * data -0.0000028 * data^2 'RH linear * With temperature correction: * fRH = (fTemp - 25) * (0.01 + 0.00008 * data) + fRH 'RH true * - Temperature data is 14 bit * Temp(degC) = -38.4 + 0.0098 * data *****************************************************************************/ async event result_t Temperature.dataReady(uint16_t data) { float fTemp, fHumidity; fTemp = -38.4 + 0.0098*(float)data; atomic { fHumidity = -4.0 + 0.0405 * HumData -0.0000028 * HumData * HumData; fHumidity= (fTemp-25.0)* (0.01 + 0.00008 * HumData) + fHumidity; } fTemp = 10*fTemp; SODbg(DBG_USR2, "gps_shtM.Humidity: Temp(adc): %i Humidity(adc): %i Temp(degCx10): %i Humidity(%): %i \n", data,HumData,(int)fTemp, (int)fHumidity); atomic { call TempHumControl.stop(); } return SUCCESS; } async event result_t Humidity.dataReady(uint16_t data) { SODbg(DBG_USR2, "gsp_shtM.Humidity.dataReady()\n") atomic { HumData = data; } return call Temperature.getData(); } event result_t TempHumControl.startDone() { SODbg(DBG_USR2, "gps_shtM.TempHumControl.startDone()\n") call Humidity.getData(); return SUCCESS; } event result_t TempHumControl.initDone() { SODbg(DBG_USR2, "gps_shtM.TempHumControl.initDone()\n") return SUCCESS; } event result_t TempHumControl.stopDone() { SODbg(DBG_USR2, "gps_shtM.TempHumControl.stopDone()\n") state1 = SHT_DONE; return SUCCESS; } event result_t HumidityError.error(uint8_t token) { SODbg(DBG_USR2, "gps_shtM.HumidityError.error()\n") call Leds.redOff(); call Leds.yellowOff(); call Temperature.getData(); return SUCCESS; } event result_t TemperatureError.error(uint8_t token) { SODbg(DBG_USR2, "gps_shtM.Temperature.error()\n") call TempHumControl.stop(); call Leds.yellowOff(); return SUCCESS; } /****************************************************************************** * Intersema MS5534A barometric pressure/temperature sensor * - 6 cal coefficients (C1..C6) are extracted from 4, 16 bit,words from sensor * - Temperature measurement: * UT1=8*C5+20224 * dT=data-UT1 * Temp=(degC x10)=200+dT(C6+50)/1024 * - Pressure measurement: * OFF=C2*4 + ((C4-512)*dT)/1024 * SENS=C1+(C3*dT)/1024 + 24576 * X=(SENS*(PressureData-7168))/16384 - OFF * Press(mbar)= X/32+250 *****************************************************************************/ async event result_t IntersemaTemp.dataReady(uint16_t data) { float UT1,dT,Temp; float OFF,SENS,X,Press; //temperature UT1=8*(float)C5+20224; dT = (float)data-UT1; Temp = 200.0 + dT*((float)C6+50.0)/1024.0; //pressure OFF = (float)C2*4 + (((float)C4-512.0)*dT)/1024; SENS = (float)C1 + ((float)C3*dT)/1024 + 24576; atomic { X = (SENS*((float)PressureData-7168.0))/16384 - OFF; } Press = X/32.0 + 250.0; SODbg(DBG_USR2, "Pressure: Temp(adc): %i Press(adc): %i Temp(degCx10): %i Press(mbar): %i \n", data,PressureData,(int)Temp, (int)Press); // FIXME: PressureControl is wired to SplitControl in IntersemaPressureM, // and called asynchronously from here, which needs to be fixed. call PressureControl.stop(); return SUCCESS; } async event result_t IntersemaPressure.dataReady(uint16_t data) { atomic { PressureData = data; } return call IntersemaTemp.getData(); } event result_t IntersemaCal.dataReady(char word, uint16_t value) { // make sure we get all the calibration bytes count++; // SODbg(DBG_USR2, " cal word %i value %x \n",word,value); calibration[word-1] = value; if (count == 4) { SODbg(DBG_USR2, "Pressure cal words (1..4): %x,%x,%x,%x \n", calibration[0],calibration[1],calibration[2],calibration[3] ); atomic { C1 = calibration[0] >> 1; C2 = ((calibration[2] & 0x3f) << 6) | (calibration[3] & 0x3f); C3 = calibration[3] >> 6; C4 = calibration[2] >> 6; C5 = ((calibration[0] & 1) << 10) | (calibration[1] >> 6); C6 = calibration[1] & 0x3f; } // SODbg(DBG_USR2, "Pressure C1:%x C2:%x C3:%x C4:%x C5:%x C6:%x \n", // C1,C2,C3,C4,C5,C6 ); SODbg(DBG_USR2, "Pressure C1:%i C2:%i C3:%i C4:%i C5:%i C6:%i \n", C1,C2,C3,C4,C5,C6 ); call IntersemaPressure.getData(); } return SUCCESS; } event result_t PressureControl.initDone() { return SUCCESS; } event result_t PressureControl.stopDone() { state1 = PRESSURE_DONE; SODbg(DBG_USR2, "gps_sht_baroM.PressureControl.stopDone()\n"); return SUCCESS; } event result_t PressureControl.startDone() { count = 0; call IntersemaCal.getData(); return SUCCESS; } /** * Taos- tsl2250 light sensor * Two ADC channels: * ADC Count Value (ACNTx) = INT(16.5*[CV-1]) +S*CV * where CV = 2^^C * C = (data & 0x7) >> 4 * S = data & 0xF * Light level (lux) = ACNT0*0.46*(e^^-3.13*R) * R = ACNT1/ACNT0 */ async event result_t TaosCh1.dataReady(uint16_t data) { uint16_t CV1,CH1,ST1,ACNT0,ACNT1; float CNT1,R,Lux; call Leds.greenToggle(); atomic { ST1 = TaosData & 0xf; } atomic { CH1 = (TaosData & 0x70) >> 4; } CV1 = 1 << CH1; CNT1 = (int)(16.5*(CV1-1)) + ST1*CV1; ACNT0 = (int)CNT1; atomic { if (TaosData == 0xff) { SODbg(DBG_USR2, "Taos Ch0 data: OVERFLOW \n") ; } } SODbg(DBG_USR2, "Taos Ch0 data: %i Cord: %i Step: %i ADC Counts: %i \n", TaosData & 0x0FF, CH1,ST1,ACNT0); data = data & 0xff; ST1 = data & 0xf; CH1 = (data & 0x70) >> 4; CV1 = 1 << CH1; CNT1 = (int)(16.5*(CV1-1)) + ST1*CV1; ACNT1 = (int)CNT1; R = (float)ACNT1/(float)ACNT0; Lux = (float)ACNT0*0.46/exp(3.13*R); if (data == 0xff) { SODbg(DBG_USR2, "Taos Ch1 data: OVERFLOW \n"); } SODbg(DBG_USR2, "Taos Ch1 data: %i Cord: %i Step: %i ADC Counts: %i Light(lux): %i \n", data & 0x0FF, CH1,ST1,ACNT1,(int)Lux); call TaosControl.stop(); return SUCCESS; } async event result_t TaosCh0.dataReady(uint16_t data) { atomic { TaosData = data & 0xff; } SODbg(DBG_USR2, "Got Taos Ch0 data \n") ; return call TaosCh1.getData(); } event result_t TaosControl.startDone(){ return call TaosCh0.getData(); } event result_t TaosControl.initDone() { return SUCCESS; } event result_t TaosControl.stopDone() { state1 = LIGHT_DONE; return SUCCESS; } } |