/* Based on the SimpleDataPlotting sketch for Uno * It reads Analog Input A0 once a second and sends the reading to an Android mobile running pfodApp * where it is plotted. * * This version add plots and requires V2.1.16 of pfodApp to display the plots * 23rd Nov 2013 * *(c)2012-15 Forward Computing and Control Pty. Ltd. * This code may be freely used for both private and commerical use. * Provide this copyright is maintained. */ // Code updated 5th Jan 2015 to use same format as Version 2 of the pfodParser Library // Using Serial and 9600 for send and receive // Serial D0 (RX) and D1 (TX) on Arduino Uno, // This code uses Serial so remove Bluetooth shield when programming the board // ====================== // this is the pfodParser.h file with the class renamed pfodParser_codeGenerated and with comments, constants and un-used methods removed class pfodParser_codeGenerated: public Print { public: pfodParser_codeGenerated(); void connect(Stream* ioPtr); void closeConnection(); byte parse(); byte* getCmd(); byte* getFirstArg(); byte getArgsCount(); byte* parseLong(byte* idxPtr, long *result); size_t write(uint8_t c); void flush(); void init(); byte parse(byte in); Stream* getPfodAppStream(); private: Stream* io; byte argsCount; byte argsIdx; byte parserState; byte args[255]; }; //============= end of pfodParser_codeGenerated.h pfodParser_codeGenerated parser; // create a parser to handle the pfod messages int analogPin = 3; // potmeter connected to A3; potentio meter is used to log a visual observation int val = 0; // used to store A3 reading #include unsigned long analogPinTimer = 0; // repeating timer #define ANALOG_PIN_TIMER_INTERVAL 5000 // 5 sec interval unsigned long lastMillis; // for outputing analog reading every 1 sec float T_int = 0; // T_int = temperatue inside the scale casing, provided by the Dalles temperature sensor float T_env = 0; // T_env = temperature of the environment float T_pan = 0; // T_pan = water temperature in the pan // scale #include "HX711.h" HX711 scale(A1, A0, 128); // parameter "gain" is ommited; the default value 128 is used by the library; A1 = DT, A0 = SCK) #include #include // library : https://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html OneWire ds_1(2); //sensor T_int on pin 2 OneWire ds_2(3); //sensor T_env on pin 3 OneWire ds_3(11); //sensor T_pan on pin 11 //Then search every pin for its address and request temps DallasTemperature sensor_1(&ds_1); DallasTemperature sensor_2(&ds_2); DallasTemperature sensor_3(&ds_3); long weight_average; double weight_value; float get_units; float weight1; // the setup routine runs once, when you press reset: void setup() { Serial.begin(9600); for (int i = 5; i > 0; i--) { // wait a few secs to see if we are being programmed delay(1000); scale.set_scale(101.f); // this value is obtained by calibrating the scale with known weights scale.tare(); // reset the scale to 0 } parser.connect(&Serial); // connect the parser to the i/o stream analogReference(DEFAULT); // sets 5V ref on UNO (sets 3.3V ref on boards with a 3.3V supply) analogPinTimer = millis(); // do this last in setup } // the loop routine runs over and over again forever: void loop() { unsigned long thisMillis = millis(); // do this just once to prevent getting different answers from multiple calls to millis() byte cmd = parser.parse(); if (cmd != 0) { // have parsed a complete msg { to } if ('.' == cmd) { // pfodApp has asked for main menu // send back "open plotting screen" parser.print(F("{=Wood Gas Stove Tester|Time(sec)`0|T_int`1|T_env`1|T_pan`1|Run`1|Weight`2}")); // this is the main menu; 4 measurements in graph 1 and 1 in graph 2 } else if ('!' == cmd) { // CloseConnection command closeConnection(parser.getPfodAppStream()); } else { // unknown command parser.print(F("{}")); // always send back a pfod msg otherwise pfodApp will disconnect. } } // see if we should output current digital pin values // once each second if ((thisMillis - analogPinTimer) > ANALOG_PIN_TIMER_INTERVAL) { // reset timer since this is a repeating timer analogPinTimer += ANALOG_PIN_TIMER_INTERVAL; // note this prevents the delay accumulating if we miss a mS or two // if we want exactly 1000 delay to next time even if this one was late then just use timeOut = 1000; // output on timer val = analogRead(analogPin); // 0..1023 val = val * ( 40 / 1023) + 11; // val is used to write visual observations as a number to the log file using a potentio meter; value of val is between 19 & 25 and is shown in the same graph as the temperature. sensor_1.begin(); sensor_1.requestTemperatures(); T_int = sensor_1.getTempCByIndex(0); sensor_2.begin(); sensor_2.requestTemperatures(); T_env = sensor_2.getTempCByIndex(0); sensor_3.begin(); sensor_3.requestTemperatures(); T_pan = sensor_3.getTempCByIndex(0); weight1 = scale.get_units(25), 0; // = average of 25 reading measurements // output the current time and reading in csv format parser.print(thisMillis / 1000.0); // first field is time in secs division using floats parser.print(","); // comma separates fields parser.print(T_int); parser.print(","); // comma separates fields parser.print(T_env); parser.print(","); // comma separates fields parser.print(T_pan); parser.print(","); // comma separates fields parser.print(val); parser.print(","); // comma separates fields parser.println(-weight1); // new line terminates data record } } void setScaleTare(){ scale.tare(); // reset the scale to 0 Serial.println("{}"); // always return something to PFOD app } void closeConnection(Stream *io) { // add any special code here to force connection to be dropped } //========================================================================= /* You can remove from here on if you have the pfodParser library installed * and add #include #include * at the top of this file * and replace the line pfodParser_codeGenerated parser; // create a parser to handle the pfod messages * with pfodParser parser; */ // this is the pfodParser.cpp file with the class renamed pfodParser_codeGenerated and with comments, constants and un-used methods removed pfodParser_codeGenerated::pfodParser_codeGenerated() { io = NULL; init(); } void pfodParser_codeGenerated::init() { argsCount = 0; argsIdx = 0; args[0] = 0; args[1] = 0; parserState = ((byte)0xff); } void pfodParser_codeGenerated::connect(Stream* ioPtr) { init(); io = ioPtr; } void pfodParser_codeGenerated::closeConnection() { init(); } Stream* pfodParser_codeGenerated::getPfodAppStream() { return io; } size_t pfodParser_codeGenerated::write(uint8_t c) { if (!io) { return 1; // cannot write if io null but just pretend to } return io->write(c); } void pfodParser_codeGenerated::flush() { if (!io) { return ; // cannot write if io null but just pretend to } io->flush(); } byte* pfodParser_codeGenerated::getCmd() { return args; } byte* pfodParser_codeGenerated::getFirstArg() { byte* idxPtr = args; while ( *idxPtr != 0) { ++idxPtr; } if (argsCount > 0) { ++idxPtr; } return idxPtr; } byte pfodParser_codeGenerated::getArgsCount() { return argsCount; } byte pfodParser_codeGenerated::parse() { byte rtn = 0; if (!io) { return rtn; } while (io->available()) { int in = io->read(); rtn = parse((byte)in); if (rtn != 0) { // found msg if (rtn == '!') { closeConnection(); } return rtn; } } return rtn; } byte pfodParser_codeGenerated::parse(byte in) { if ((parserState == ((byte)0xff)) || (parserState == ((byte)'}'))) { parserState = ((byte)0xff); if (in == ((byte)'{')) { init(); parserState = ((byte)'{'); } return 0; } if ((argsIdx >= (255 - 2)) && (in != ((byte)'}'))) { init(); return 0; } if (parserState == ((byte)'{')) { parserState = ((byte)0); } if ((in == ((byte)'}')) || (in == ((byte)'|')) || (in == ((byte)'~')) || (in == ((byte)'`'))) { args[argsIdx++] = 0; if (parserState == ((byte)0xfe)) { argsCount++; } if (in == ((byte)'}')) { parserState = ((byte)'}'); // reset state return args[0]; } else { parserState = ((byte)0xfe); } return 0; } args[argsIdx++] = in; return 0; } byte* pfodParser_codeGenerated::parseLong(byte* idxPtr, long *result) { long rtn = 0; boolean neg = false; while ( *idxPtr != 0) { if (*idxPtr == '-') { neg = true; } else { rtn = (rtn << 3) + (rtn << 1); rtn = rtn + (*idxPtr - '0'); } ++idxPtr; } if (neg) { rtn = -rtn; } *result = rtn; return ++idxPtr; } // ============= end generated code =========