diff --git a/README.md b/README.md index 279dfed..bf79717 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,11 @@ The purpose of this library is to use the phyphox app (see www.phyphox.org) to p - Arduino Nano 33 Ble - Arduino Nano Sense - Arduino Nano 33 IoT (see note below) +- Arduino Uno R4 Wifi (see note below) - senseBox MCU with NINA-B31 module - ESP 32 -Note: The Arduino Nano 33 IoT is somewhat unusual. You will need to install the ArduinoBLE library to use it and you will need to call "PhyphoxBLE::poll()" periodically for it to work. See the "randomNumbers-IoT" example. +Note: The Arduino Nano 33 IoT and the Arduino uno R4 are somewhat unusual. You will need to install the ArduinoBLE library to use it and you will need to call "PhyphoxBLE::poll()" periodically for it to work. Note: When using the NINA-B31 module you must call PhyphoxBLE::poll() periodically (in loop() ) or the library will not work. @@ -70,6 +71,7 @@ Here are some useful methods to create your own experiment: | Experiment | setDescription(char*) | Sets a description for the experiment | | Experiment | addView(View&) | Adds a view to the corresponding experiment | | Experiment | addExportSet(ExportSet&) | Adds an exportSet to the corresponding experiment | +| Experiment | addSensor(Sensor&) | Data from smarpthone sensor can will be received (see getSensorDataFromSmartphone example)| | View | addElement(Element&) | Adds an element to the corresponding view | | View | setLabel(char*) | Sets a label for the view | | Graph | setLabel(char*) | Sets a label for the graph | @@ -77,8 +79,14 @@ Here are some useful methods to create your own experiment: | Graph | setLabelX(char*) | Sets a label for x (similar with y) | | Graph | setXPrecision(int) | Sets the amount of digits after the decimal point (similar with y)| | Graph | setChannel(int, int) | As explained above (1-5) | -| Graph | setStyle(char*) | Sets the style. For more possibilities check the wiki | +| Graph | addSubgraph(Subgraph) | Adds an additional subgraph (see example "multigraph") | +| Graph | setStyle(char*) | Sets the style (use defines: STYLE_LINES, STYLE_DOTS). | | Graph | setColor(char*) | Sets the line color of the graph (use a 6 digit hexadecimal code) | +| Graph | setMinX(int, const char *)| Sets the min x value of the co-system and a layout (auto, extend and fixed) | +| Graph | setMaxX(int, const char *)| Sets the max x value of the co-system and a layout (auto, extend and fixed) | +| Graph | setMinY(int, const char *)| Sets the min y value of the co-system and a layout (auto, extend and fixed) | +| Graph | setMaxY(int, const char *)| Sets the max y value of the co-system and a layout (auto, extend and fixed) | +| Graph | setLineWidth(float) | Sets the line width | | Separator | setHeight(float) | Creates a line to separate parts of the experiment | | Separator | setColor(char*) | Sets the color of the line (use a 6 digit hexadecimal code) | | Info | setInfo(char*) | Sets the infotext | @@ -98,11 +106,20 @@ Here are some useful methods to create your own experiment: | ExportData | setDatachannel(int) | Defines which channel should be exported for this dataset (1-5) | | Everything | setXMLAttribute(char*) | Custom property e.g. setXMLAttribute("lineWidth=\"3\"") | + +#### Style and Layout oprtions for setStyle and setMax/setMin +STYLE_LINES, STYLE_DOTS, STYLE_VBARS, STYLE_HBARS, STYLE_MAP + +LAYOUT_AUTO, LAYOUT_EXTEND, LAYOUT_FIXED + +#### Error messages + If for some reason the app shows you an error in form of "ERROR FOUND: ERR_X", with different values for X, this could be the reason: -* ERR_01: The input was too long -* ERR_02: The value exceeds the upper limit -* ERR_03: The input was not a 6-digit hexadecimal code -* ERR_04: The input does not match with a valid value +* ERR_01: The input was too long. +* ERR_02: The value exceeds the upper limit. +* ERR_03: The input was not a 6-digit hexadecimal code. +* ERR_04: The input does not match with a valid value. +* ERR_05: The layout must be auto, extend or fixed. If you realize that the microcontroller is continiously rebooting, you maybe added too many elements. @@ -129,7 +146,7 @@ If you can help with this, we are happy to receive a pull request. You can conta ## Credits -This library has been developed by the phyphox team at the RWTH Aachen University. In particular, the foundations and basic concept was created by Alexander Krampe as part of his Master thesis. The library has been further improved and is now maintained by Dominik Dorsel, our PhD student who also supervised Alexander's thesis. +This library has been developed by the phyphox team at the RWTH Aachen University. In particular, the foundations and basic concept was created by Alexander Krampe as part of his Master thesis. The library has been further improved and is now maintained by Dominik Dorsel, our PhD student who also supervised Alexander's thesis. The library was also further optimized and extended with new features by Marcel Hagedorn and Edward Leier. ## Licence diff --git a/examples/CreateExperiment/CreateExperiment.ino b/examples/CreateExperiment/CreateExperiment.ino index f7ad29c..3262fc2 100644 --- a/examples/CreateExperiment/CreateExperiment.ino +++ b/examples/CreateExperiment/CreateExperiment.ino @@ -1,17 +1,15 @@ #include -float editValue = 0; - void setup() { Serial.begin(115200); - PhyphoxBLE::start("My Device"); - PhyphoxBLE::configHandler = &receivedData; // used to receive data from PhyPhox. + PhyphoxBLE::start("create experiment"); //Experiment PhyphoxBleExperiment plotRandomValues; //generate experiment on Arduino which plot random values - plotRandomValues.setTitle("Random Number Plotter"); + + plotRandomValues.setTitle("Create Experiment"); plotRandomValues.setCategory("Arduino Experiments"); plotRandomValues.setDescription("Random numbers are generated on Arduino and visualized with phyphox afterwards"); @@ -23,6 +21,8 @@ void setup() //Graph PhyphoxBleExperiment::Graph firstGraph; //Create graph which will plot random numbers over time + firstGraph.setMinY(0, LAYOUT_FIXED); + firstGraph.setMaxY(100, LAYOUT_FIXED); firstGraph.setLabel("Random number over time"); firstGraph.setUnitX("s"); firstGraph.setUnitY(""); @@ -38,29 +38,31 @@ void setup() */ firstGraph.setChannel(0, 1); - + //Second Graph + PhyphoxBleExperiment::Graph secondGraph; //Create graph which will plot random numbers over time secondGraph.setLabel("Random number squared over random number"); secondGraph.setUnitX(""); secondGraph.setUnitY(""); secondGraph.setLabelX("random number"); secondGraph.setLabelY("squared"); - secondGraph.setStyle("dots"); + secondGraph.setStyle(STYLE_DOTS); secondGraph.setColor("2E728E"); //Sets Color of line - + /* Assign Channels, so which data is plotted on x or y axis first parameter represents x-axis, second y-axis Channel 0 means a timestamp is created after the BLE package arrives in phyphox Channel 1 to N corresponding to the N-parameter which is written in server.write() */ - + secondGraph.setChannel(1, 2); + //Info PhyphoxBleExperiment::InfoField myInfo; //Creates an info-box. - myInfo.setInfo("In this view you can set a value between 1 and 10. The squared random value will be multiplied by this value and can be seen here."); - //myInfo.setColor("404040"); //Sets font color. Uses a 6 digit hexadecimal value in "quotation marks". + myInfo.setInfo("This is an Info field!"); + myInfo.setColor("890128"); //Sets font color. Uses a 6 digit hexadecimal value in "quotation marks". myInfo.setXMLAttribute("size=\"1.2\""); //Separator @@ -72,24 +74,14 @@ void setup() PhyphoxBleExperiment::Value myValue; //Creates a value-box. myValue.setLabel("Number"); //Sets the label myValue.setPrecision(2); //The amount of digits shown after the decimal point. - myValue.setUnit("u"); //The physical unit associated with the displayed value. + myValue.setUnit("unit"); //The physical unit associated with the displayed value. myValue.setColor("FFFFFF"); //Sets font color. Uses a 6 digit hexadecimal value in "quotation marks". - myValue.setChannel(3); + myValue.setChannel(0); myValue.setXMLAttribute("size=\"2\""); - //Edit - PhyphoxBleExperiment::Edit myEdit; - myEdit.setLabel("Editfield"); - myEdit.setUnit("u"); - myEdit.setSigned(false); - myEdit.setDecimal(false); - myEdit.setChannel(1); - myEdit.setXMLAttribute("max=\"10\""); - //Export PhyphoxBleExperiment::ExportSet mySet; //Provides exporting the data to excel etc. mySet.setLabel("mySet"); - PhyphoxBleExperiment::ExportData myData1; myData1.setLabel("myData1"); myData1.setDatachannel(1); @@ -105,7 +97,7 @@ void setup() secondView.addElement(myInfo); //attach info to view secondView.addElement(mySeparator); //attach separator to view secondView.addElement(myValue); //attach value to view - secondView.addElement(myEdit); //attach editfield to view (Linked to value) + plotRandomValues.addView(firstView); //attach view to experiment plotRandomValues.addView(secondView); mySet.addElement(myData1); //attach data to exportSet @@ -117,22 +109,14 @@ void setup() void loop() { - float randomValue = random(0, 100); //create random number between 0 - 100 float randomValue2 = randomValue * randomValue; /* The random number is written into Channel 1 Up to 5 Channels can written at the same time with server.write(randomDistance, valueChannel2, valueChannel3.. ) */ - float tmp = randomValue2*editValue; - PhyphoxBLE::write(randomValue, randomValue2, tmp); + PhyphoxBLE::write(randomValue, randomValue2); delay(50); PhyphoxBLE::poll(); //Only required for the Arduino Nano 33 IoT, but it does no harm for other boards. -} - -void receivedData() { // get data from PhyPhox app - float readInput; - PhyphoxBLE::read(readInput); - editValue = readInput; } \ No newline at end of file diff --git a/examples/getDataFromSmartphone/getDataFromSmartphone.ino b/examples/getDataFromSmartphone/getDataFromSmartphone.ino index 3759843..bcaa43b 100644 --- a/examples/getDataFromSmartphone/getDataFromSmartphone.ino +++ b/examples/getDataFromSmartphone/getDataFromSmartphone.ino @@ -11,7 +11,7 @@ bool led = true; void setup() { - PhyphoxBLE::begin(&Serial); + Serial.begin(115200); PhyphoxBLE::start(); PhyphoxBLE::configHandler=&receivedData; pinMode(LED_BUILTIN, OUTPUT); @@ -42,14 +42,13 @@ void setup() void loop() { - PhyphoxBLE::poll(); //Only required for the Arduino Nano 33 IoT, but it does no harm for other boards. + PhyphoxBLE::poll(); //Only required for the Arduino Nano 33 IoT, but it does no harm for other boards. if(millis()-lastTimestamp>blinkInterval){ lastTimestamp = millis(); led=!led; digitalWrite(LED_BUILTIN, led); } - } void receivedData(){ diff --git a/examples/getSensorDataFromSmartphone/getSensorDataFromSmartphone.ino b/examples/getSensorDataFromSmartphone/getSensorDataFromSmartphone.ino new file mode 100644 index 0000000..e0cd091 --- /dev/null +++ b/examples/getSensorDataFromSmartphone/getSensorDataFromSmartphone.ino @@ -0,0 +1,62 @@ +#include + +void setup() { + Serial.begin(115200); + + PhyphoxBLE::start(); + PhyphoxBLE::configHandler=&receivedData; + + PhyphoxBleExperiment getDataFromSmartphonesensor; + getDataFromSmartphonesensor.setTitle("Get Accelerometer Data"); + getDataFromSmartphonesensor.setCategory("Arduino Experiments"); + getDataFromSmartphonesensor.setDescription("Send smartphone accelerometer data to an arduino/esp32"); + + PhyphoxBleExperiment::View firstView; + firstView.setLabel("FirstView"); //Create a "view" + + PhyphoxBleExperiment::InfoField infoText; + infoText.setInfo("Acc data is sent to smartphone"); + firstView.addElement(infoText); + + PhyphoxBleExperiment::Sensor smartphoneAcc; // add new sensor + + // Set type of sensor: + // SENSOR_ACCELEROMETER + // SENSOR_ACCELEROMETER_WITHOUT_G + // SENSOR_GYROSCOPE + // SENSOR_MAGNETOMETER + // SENSOR_PRESSURE + smartphoneAcc.setType(SENSOR_ACCELEROMETER); + smartphoneAcc.setAverage(true); + smartphoneAcc.setRate(80); + + // map sensor channel to incoming data channels + smartphoneAcc.mapChannel("x",1); + smartphoneAcc.mapChannel("y",2); + smartphoneAcc.mapChannel("z",3); + + getDataFromSmartphonesensor.addView(firstView); + getDataFromSmartphonesensor.addSensor(smartphoneAcc); + + PhyphoxBLE::addExperiment(getDataFromSmartphonesensor); + PhyphoxBLE::printXML(&Serial); //print the generated xml file into the serial monitor +} + +void loop() { + delay(100); + PhyphoxBLE::poll(); //Only required for the Arduino Nano 33 IoT, but it does no harm for other boards. +} + +void receivedData(){ + Serial.println("data:"); + float x,y,z; + PhyphoxBLE::read(x,y,z); + Serial.print("x: "); + Serial.print(x); + + Serial.print(" y: "); + Serial.print(y); + + Serial.print(" z: "); + Serial.println(z); +} \ No newline at end of file diff --git a/examples/getSystemAndEventTime/getSystemAndEventTime.ino b/examples/getSystemAndEventTime/getSystemAndEventTime.ino new file mode 100644 index 0000000..44fae3a --- /dev/null +++ b/examples/getSystemAndEventTime/getSystemAndEventTime.ino @@ -0,0 +1,28 @@ +#include + +void setup() { + Serial.begin(115200); + PhyphoxBLE::start(); + PhyphoxBLE::experimentEventHandler = &newExperimentEvent; // declare which function should be called after receiving an experiment event + PhyphoxBLE::printXML(&Serial); +} + +void loop() { + float randomNumber = random(0,100); //Generate random number in the range 0 to 100 + PhyphoxBLE::write(randomNumber); //Send value to phyphox + delay(100); + PhyphoxBLE::poll(); //Only required for the Arduino Nano 33 IoT, but it does no harm for other boards. + +} + +//declare function which is called after phyphox wrote to the event characteristic +void newExperimentEvent(){ + Serial.println("New experiment event received:"); + Serial.print("Event type: "); + Serial.print(PhyphoxBLE::eventType); + Serial.println(" (0 = Paused, 1 = Started, 255 = SYNC)"); + Serial.print("Experiment time [ms]: "); + Serial.println(PhyphoxBLE::experimentTime); + Serial.print("Unix system time [ms]: "); + Serial.println(PhyphoxBLE::systemTime); +} \ No newline at end of file diff --git a/examples/multigraph/multigraph.ino b/examples/multigraph/multigraph.ino new file mode 100644 index 0000000..38f5581 --- /dev/null +++ b/examples/multigraph/multigraph.ino @@ -0,0 +1,77 @@ +#include +#include +#define PI 3.1415926535897932384626433832795 +float periodTime = 2.0;//in s + +void setup() { + Serial.begin(115200); + PhyphoxBLE::start(); + + PhyphoxBleExperiment MultiGraph; + + MultiGraph.setTitle("Multi Graph Example"); + MultiGraph.setCategory("Arduino Experiments"); + MultiGraph.setDescription("ArduinoBLE Example"); + + PhyphoxBleExperiment::View firstView; + firstView.setLabel("FirstView"); //Create a "view" + + //Multiple graphs in one plot can be realised by two different methods. + // OPTION 1 is do create a graph as usual and add additional datastreams the following way + PhyphoxBleExperiment::Graph myFirstGraph; + myFirstGraph.setChannel(1,2); + myFirstGraph.setStyle(STYLE_DOTS);//"lines" are used if you dont set a style + myFirstGraph.setColor("ffffff"); + myFirstGraph.setLinewidth(2);//if you dont select a linewidth, a width of 1 is used by default + + PhyphoxBleExperiment::Graph::Subgraph additionalData; + additionalData.setChannel(1,3); + additionalData.setStyle(STYLE_LINES); + additionalData.setColor("ff00ff"); + additionalData.setLinewidth(1); + + myFirstGraph.addSubgraph(additionalData); + + //OPTION 2: you can also skip editing the graph object and just add datastreams + PhyphoxBleExperiment::Graph mySecondGraph; + + PhyphoxBleExperiment::Graph::Subgraph firstData; + firstData.setChannel(1,2); + firstData.setColor("ffffff"); + firstData.setStyle(STYLE_DOTS); + firstData.setLinewidth(2); + + mySecondGraph.addSubgraph(firstData); + + PhyphoxBleExperiment::Graph::Subgraph secondData; + secondData.setChannel(1,3); + secondData.setColor("ff00ff"); + secondData.setLinewidth(1);//if you dont select a linewidth, a width of 1 is used by default + secondData.setStyle(STYLE_LINES); //"lines" are used if you dont set a style + + + mySecondGraph.addSubgraph(secondData); + + firstView.addElement(myFirstGraph); + firstView.addElement(mySecondGraph); + + MultiGraph.addView(firstView); + + PhyphoxBLE::addExperiment(MultiGraph); + + PhyphoxBLE::printXML(&Serial); +} + +void loop() { + + float currentTime = millis()/1000.0; + float sinus = generateSin(currentTime); + float cosinus = generateSin(currentTime+0.5*periodTime); + PhyphoxBLE::write(currentTime,sinus,cosinus); + delay(100); + PhyphoxBLE::poll(); //Only required for the Arduino Nano 33 IoT, but it does no harm for other boards. +} + +float generateSin(float x){ + return 1.0 * sin(x*2.0*PI/periodTime); +} \ No newline at end of file diff --git a/examples/randomNumbers-IoT/randomNumbers-IoT.ino b/examples/randomNumbers-IoT/randomNumbers-IoT.ino new file mode 100644 index 0000000..3f5f20c --- /dev/null +++ b/examples/randomNumbers-IoT/randomNumbers-IoT.ino @@ -0,0 +1,13 @@ +#include + +void setup() { + PhyphoxBLE::start(); //Start the BLE server +} + +void loop() { + float randomNumber = random(0,100); //Generate random number in the range 0 to 100 + PhyphoxBLE::write(randomNumber); //Send value to phyphox + delay(50); //Shortly pause before repeating + + PhyphoxBLE::poll(); //IMPORTANT: In contrast to other devices, poll() needs to be called periodically on the 33 IoT +} diff --git a/examples/randomNumbers/randomNumbers.ino b/examples/randomNumbers/randomNumbers.ino index d8f3a4f..344cd0c 100644 --- a/examples/randomNumbers/randomNumbers.ino +++ b/examples/randomNumbers/randomNumbers.ino @@ -1,11 +1,12 @@ #include void setup() { - PhyphoxBLE::start(); //Start the BLE server + PhyphoxBLE::start("phyphox device"); //Start the BLE server } void loop() { float randomNumber = random(0,100); //Generate random number in the range 0 to 100 PhyphoxBLE::write(randomNumber); //Send value to phyphox delay(50); //Shortly pause before repeating + PhyphoxBLE::poll(); //IMPORTANT: In contrast to other devices, poll() needs to be called periodically on the 33 IoT } diff --git a/library.properties b/library.properties index 2091847..61e6eeb 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ name=phyphox BLE -version=1.1.2 +version=1.2.0 author=RWTH Aachen University maintainer=Dominik Dorsel sentence=Use the app phyphox to visualize your sensor data on your phone or tablet! paragraph=The purpose of this library is to use the open source phyphox app (see https://phyphox.org) to plot sensor data on your phone. phyphox is much more than only 'plotting your data'. You can also perform data analysis with it or access your phones sensors to use in your Arduino project. category=Other url=https://phyphox.org/arduino -architectures=mbed,esp32,samd,mbed_nano +architectures=mbed,esp32,samd,mbed_nano,renesas_uno includes=phyphoxBle.h diff --git a/src/copyToMem.cpp b/src/copyToMem.cpp new file mode 100644 index 0000000..1fb7a51 --- /dev/null +++ b/src/copyToMem.cpp @@ -0,0 +1,9 @@ +#include "copyToMem.h" + +void copyToMem(char **target, const char *data) { + // if (*target != NULL) { + // free(*target); // Causes crashes + // } + *target = (char*) malloc(sizeof(char) * (strlen(data)+1)); + strcpy(*target, data); +} \ No newline at end of file diff --git a/src/copyToMem.h b/src/copyToMem.h new file mode 100644 index 0000000..d8935ce --- /dev/null +++ b/src/copyToMem.h @@ -0,0 +1,3 @@ +#include "phyphoxBleExperiment.h" + +void copyToMem(char **target, const char *data); \ No newline at end of file diff --git a/src/defines.h b/src/defines.h new file mode 100644 index 0000000..99d6b77 --- /dev/null +++ b/src/defines.h @@ -0,0 +1,18 @@ +// Experiment constants +#define phyphoxBleNViews 15 +#define phyphoxBleNSensors 5 +#define phyphoxBleNElements 20 +#define phyphoxBleNExportSets 10 +#define phyphoxBleNChannel 10 + +// Graph style options +#define STYLE_LINES "lines" +#define STYLE_DOTS "dots" +#define STYLE_VBARS "vbars" +#define STYLE_HBARS "hbars" +#define STYLE_MAP "map" + +// Graph layout options +#define LAYOUT_AUTO "auto" +#define LAYOUT_EXTEND "extend" +#define LAYOUT_FIXED "fixed" \ No newline at end of file diff --git a/src/edit.cpp b/src/edit.cpp index 6d299d7..73fc879 100644 --- a/src/edit.cpp +++ b/src/edit.cpp @@ -1,49 +1,67 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" void PhyphoxBleExperiment::Edit::setUnit(const char *u) { - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(u, 12, "setUnit") : ERROR; - memset(&UNIT[0], 0, sizeof(UNIT)); - strcat(UNIT, " unit=\""); - strcat(UNIT, u); - strcat(UNIT, "\""); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(u, 12, "setUnit") : ERROR; + copyToMem(&UNIT, (std::string(u)).c_str()); } void PhyphoxBleExperiment::Edit::setSigned(bool s) { - if(s) sprintf(SIGNED, " signed=\"true\""); - else sprintf(SIGNED, " signed=\"false\""); + if(s) copyToMem(&SIGNED, "true"); + else copyToMem(&SIGNED, "false"); } void PhyphoxBleExperiment::Edit::setDecimal(bool d) { - if(d) sprintf(SIGNED, " decimal=\"true\""); - else sprintf(SIGNED, " decimal=\"false\""); + if(d) copyToMem(&DECIMAL, "true"); + else copyToMem(&DECIMAL, "false"); } void PhyphoxBleExperiment::Edit::setXMLAttribute(const char *xml){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(xml, 98, "setXMLAttribute") : ERROR; - memset(&XMLAttribute[0], 0, sizeof(XMLAttribute)); - strcat(XMLAttribute, " "); - strcat(XMLAttribute, xml); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(xml, 98, "setXMLAttribute") : ERROR; + copyToMem(&XMLAttribute, (" " + std::string(xml)).c_str()); } void PhyphoxBleExperiment::Edit::setChannel(int b){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkUpper(b, 1, "setChannel") : ERROR; - sprintf(BUFFER, "CB%i", b); + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(b, 5, "setChannel") : ERROR; + char tmp[20]; + sprintf(tmp, "CB%i", b); + copyToMem(&BUFFER, tmp); } void PhyphoxBleExperiment::Edit::getBytes(char *buffArray) { - strcat(buffArray,"\t\t\n"); strcat(buffArray,"\t\t"); - strcat(buffArray, BUFFER); + if (!BUFFER) {strcat(buffArray,"CH5");} else {strcat(buffArray,BUFFER);} strcat(buffArray,"\n"); strcat(buffArray, "\t\t\n"); } diff --git a/src/element.cpp b/src/element.cpp index 8f55758..8648c74 100644 --- a/src/element.cpp +++ b/src/element.cpp @@ -1,9 +1,11 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" void PhyphoxBleExperiment::Element::setLabel(const char *l){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(l, 41, "setLabel") : ERROR; - memset(&LABEL[0], 0, sizeof(LABEL)); - strcat(LABEL, " label=\""); - strcat(LABEL, l); - strcat(LABEL, "\""); -} \ No newline at end of file + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(l, 41, "setLabel") : ERROR; + copyToMem(&LABEL, (std::string(l)).c_str()); +} + +// void PhyphoxBleExperiment::Element::setLabel(const char *l){ +// copyToMem(&LABEL, (" label=\"" + std::string(l) + "\"").c_str()); +// } diff --git a/src/error.cpp b/src/error.cpp index 654f464..5d86a61 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -1,8 +1,9 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" void PhyphoxBleExperiment::Error::getBytes(char *buffArray) { strcat(buffArray,"\t\t\n"); strcat(buffArray,"\t\t\n"); } diff --git a/src/errorhandler.cpp b/src/errorhandler.cpp index 94f0fcc..4771372 100644 --- a/src/errorhandler.cpp +++ b/src/errorhandler.cpp @@ -1,11 +1,11 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" + PhyphoxBleExperiment::Error PhyphoxBleExperiment::Errorhandler::err_checkLength(const char *input, int maxLength, const char *origin) { Error ret; if(strlen(input) > maxLength) { - strcat(ret.MESSAGE, "ERR_01, in "); - strcat(ret.MESSAGE, origin); - strcat(ret.MESSAGE, "(). \n"); + copyToMem(&ret.MESSAGE, ("ERR_01, in " + std::string(origin) + "(). \n").c_str()); } return ret; } @@ -13,9 +13,7 @@ PhyphoxBleExperiment::Error PhyphoxBleExperiment::Errorhandler::err_checkLength( PhyphoxBleExperiment::Error PhyphoxBleExperiment::Errorhandler::err_checkUpper(int input, int upperValue, const char *origin) { Error ret; if(input > upperValue) { - strcat(ret.MESSAGE, "ERR_02, in "); - strcat(ret.MESSAGE, origin); - strcat(ret.MESSAGE, "(). \n"); + copyToMem(&ret.MESSAGE, ("ERR_02, in " + std::string(origin) + "(). \n").c_str()); } return ret; } @@ -23,15 +21,11 @@ PhyphoxBleExperiment::Error PhyphoxBleExperiment::Errorhandler::err_checkUpper(i PhyphoxBleExperiment::Error PhyphoxBleExperiment::Errorhandler::err_checkHex(const char* input, const char *origin){ Error ret; if(strlen(input) != 6) { - strcat(ret.MESSAGE, "ERR_03, in "); - strcat(ret.MESSAGE, origin); - strcat(ret.MESSAGE, "(). \n"); + copyToMem(&ret.MESSAGE, ("ERR_03, in " + std::string(origin) + "(). \n").c_str()); }; for(int i=0; i<=5; i++) { if(!((input[i] <='f' && input[i] >='a') || (input[i] <='F' && input[i] >='A') || (input[i] <='9' && input[i] >='0'))) { - strcat(ret.MESSAGE, "ERR_03, in "); - strcat(ret.MESSAGE, origin); - strcat(ret.MESSAGE, "(). \n"); + copyToMem(&ret.MESSAGE, ("ERR_03, in " + std::string(origin) + "(). \n").c_str()); } } return ret; @@ -40,9 +34,29 @@ PhyphoxBleExperiment::Error PhyphoxBleExperiment::Errorhandler::err_checkHex(con PhyphoxBleExperiment::Error PhyphoxBleExperiment::Errorhandler::err_checkStyle(const char *input, const char *origin) { Error ret; if(strcmp(input,"lines")!=0 && strcmp(input,"dots")!=0 && strcmp(input,"vbars")!=0 && strcmp(input,"hbars")!=0 && strcmp(input,"map")!=0) { - strcat(ret.MESSAGE, "ERR_04, in "); - strcat(ret.MESSAGE, origin); - strcat(ret.MESSAGE, "(). \n"); + copyToMem(&ret.MESSAGE, ("ERR_04, in " + std::string(origin) + "(). \n").c_str()); + } + return ret; +} + +PhyphoxBleExperiment::Error PhyphoxBleExperiment::Errorhandler::err_checkLayout(const char *input, const char *origin) { + Error ret; + copyToMem(&ret.MESSAGE, ("ERR_05, in " + std::string(origin) + "(). \n").c_str()); + return ret; +} + +PhyphoxBleExperiment::Error PhyphoxBleExperiment::Errorhandler::err_checkSensor(const char *input, const char *origin) { + Error ret; + if(strcmp(input,"accelerometer")!=0 && strcmp(input,"linear_acceleration")!=0 && strcmp(input,"gyroscope")!=0 && strcmp(input,"light")!=0 && strcmp(input,"magnetic_field")!=0 && strcmp(input,"pressure")!=0 && strcmp(input,"temperature")!=0) { + copyToMem(&ret.MESSAGE, ("ERR_04, in " + std::string(origin) + "(). \n").c_str()); + } + return ret; +} + +PhyphoxBleExperiment::Error PhyphoxBleExperiment::Errorhandler::err_checkComponent(const char *input, const char *origin) { + Error ret; + if(strcmp(input,"x")!=0 && strcmp(input,"y")!=0 && strcmp(input,"z")!=0 && strcmp(input,"abs")!=0 && strcmp(input,"accuracy")!=0 && strcmp(input,"t")!=0) { + copyToMem(&ret.MESSAGE, ("ERR_04, in " + std::string(origin) + "(). \n").c_str()); } return ret; } \ No newline at end of file diff --git a/src/experiment.cpp b/src/experiment.cpp index befcef9..90ca7e1 100644 --- a/src/experiment.cpp +++ b/src/experiment.cpp @@ -1,6 +1,10 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" +#include "phyphoxBle.h" int PhyphoxBleExperiment::numberOfChannels = 5; + + void PhyphoxBleExperiment::addView(View& v) { for(int i=0; isetLabel("SENSOR RAW DATA"); + VIEWS[phyphoxBleNViews-1] = RawDataSmartoneSensor; + InfoField* SensorType = new InfoField(); + SensorType->INFO = s.TYPE; + for (int j = 0; j < phyphoxBleNElements; j++){ + if(VIEWS[phyphoxBleNViews-1]->ELEMENTS[j]==nullptr){ + VIEWS[phyphoxBleNViews-1]->ELEMENTS[j] = SensorType; + break; + } + } + + } + + for(int mappedCH = 0; mappedCH<5; mappedCH++){ + if( s.CHANNEL[mappedCH]!=nullptr){ + for (int j = 0; j < phyphoxBleNElements; j++){ + if(VIEWS[phyphoxBleNViews-1]->ELEMENTS[j]==nullptr){ + PhyphoxBleExperiment::Value* newValueField = new Value(); + newValueField->INPUTVALUE = s.CHANNEL[mappedCH]; + newValueField->LABEL = s.COMPONENT[mappedCH]; + VIEWS[phyphoxBleNViews-1]->ELEMENTS[j]=newValueField; + break; + } + } + } + } + + break; + } + } +} + void PhyphoxBleExperiment::setTitle(const char *t){ - memset(&TITLE[0], 0, sizeof(TITLE)); - strcat(TITLE, t); + copyToMem(&TITLE, t); } void PhyphoxBleExperiment::setCategory(const char *c){ - memset(&CATEGORY[0], 0, sizeof(CATEGORY)); - strcat(CATEGORY, c); + copyToMem(&CATEGORY, c); } void PhyphoxBleExperiment::setDescription(const char *d){ - memset(&DESCRIPTION[0], 0, sizeof(DESCRIPTION)); - strcat(DESCRIPTION, d); + copyToMem(&DESCRIPTION, d); } -void PhyphoxBleExperiment::setConfig(const char *t){ - memset(&CONFIG[0], 0, sizeof(CONFIG)); - strcat(CONFIG, t); +void PhyphoxBleExperiment::setColor(const char *c){ + copyToMem(&COLOR, (std::string(c)).c_str()); +} + +void PhyphoxBleExperiment::setRepeating(const int r){ + PhyphoxBleExperiment::repeating = r; +} +void PhyphoxBleExperiment::setSubscribeOnStart(bool b) { + if(b) copyToMem(&SUBSCRIBEONSTART, "true"); + else copyToMem(&SUBSCRIBEONSTART, "false"); } +// void PhyphoxBleExperiment::setConfig(const char *c){ +// copyToMem(&CONFIG, c); +// } + void PhyphoxBleExperiment::addExportSet(ExportSet& e) { for(int i=0; i\n"); + strcat(buffArray, "\n"); //build title strcat(buffArray,""); - strcat(buffArray, TITLE); + if (!TITLE) {strcat(buffArray,"Arduino-Experiment");} else {strcat(buffArray,TITLE);} strcat(buffArray,"\n"); //build category strcat(buffArray, ""); - strcat(buffArray, CATEGORY); + if (!CATEGORY) {strcat(buffArray,"Arduino Experiments");} else {strcat(buffArray,CATEGORY);} strcat(buffArray, "\n"); + //build color + /* + if (!COLOR){ + strcat(buffArray, ""); + strcat(buffArray,COLOR); + strcat(buffArray, "\n"); + } + */ + //build description strcat(buffArray, ""); - strcat(buffArray, DESCRIPTION); + if (!DESCRIPTION) { + strcat(buffArray,"An experiment created with the phyphox BLE library for Arduino-compatible micro controllers."); + }else { + strcat(buffArray,DESCRIPTION); + } strcat(buffArray, "\n"); //build container strcat(buffArray, "\n"); strcat(buffArray, "\tCH0\n"); strcat(buffArray, "\tCB1\n"); + strcat(buffArray, "\tCB2\n"); + strcat(buffArray, "\tCB3\n"); + strcat(buffArray, "\tCB4\n"); + strcat(buffArray, "\tCB5\n"); + for(int i=0; iCH"); char add[20]; @@ -87,25 +158,27 @@ void PhyphoxBleExperiment::getFirstBytes(char *buffArray, const char *DEVICENAME sprintf(add, "\" mtu=\"%i", MTU); strcat(buffArray, add); } - strcat(buffArray, "\" id=\"phyphoxBLE\" mode=\"notification\" rate=\"1\" subscribeOnStart=\"false\">\n"); + strcat(buffArray, "\" id=\"phyphoxBLE\" mode=\"notification\" subscribeOnStart=\""); + if (!SUBSCRIBEONSTART) {strcat(buffArray, "false");} else {strcat(buffArray, SUBSCRIBEONSTART);} + strcat(buffArray, "\">\n\t\t"); //build config //strcat(buffArray,"\t\t"); - //strcat(buffArray, CONFIG); + // if (!CONFIG) {strcat(buffArray,"000000");} else {strcat(buffArray,CONFIG);} //strcat(buffArray,"\n\t\t"); if(repeating <= 0){ for(int i=1; i<=numberOfChannels;i++){ - strcat(buffArray, "CH%i", k,i); + sprintf(add, "offset=\"%i\">CH%i", k,i); strcat(buffArray, add); - strcat(buffArray,"\n\t\t"); + strcat(buffArray,"\n"); } }else{ for(int i=1; i<=numberOfChannels;i++){ @@ -121,13 +194,23 @@ void PhyphoxBleExperiment::getFirstBytes(char *buffArray, const char *DEVICENAME strcat(buffArray,"CH0"); strcat(buffArray, "\n\t\n"); + //build sensor input + + for (int i = 0; i < phyphoxBleNSensors; i++) + { + if(SENSORS[i] != nullptr){ + //strcat(buffArray, "\n\t\tCB1"); + SENSORS[i]->getBytes(buffArray); + } + } strcat(buffArray, "\n"); + //build output strcat(buffArray, "\n"); strcat(buffArray, "\t\n"); + strcat(buffArray, "\">\n\t\t"); // for(int i=1; i<=1;i++){ // strcat(buffArray, "\n\t\t"); // } strcat(buffArray, "\t\tCB1\n"); + strcat(buffArray, "\t\tCB2\n"); + strcat(buffArray, "\t\tCB3\n"); + strcat(buffArray, "\t\tCB4\n"); + strcat(buffArray, "\t\tCB5\n"); strcat(buffArray, "\t\n"); strcat(buffArray, "\n"); //build analysis - strcat(buffArray, "\n"); + strcat(buffArray, "\n"); //build views strcat(buffArray, "\n"); @@ -153,7 +240,7 @@ void PhyphoxBleExperiment::getFirstBytes(char *buffArray, const char *DEVICENAME for(int j=0;jELEMENTS[j]!=nullptr){ - if(strcmp(VIEWS[i]->ELEMENTS[j]->ERROR.MESSAGE, "") != 0) { + if(VIEWS[i]->ELEMENTS[j]->ERROR.MESSAGE != NULL) { if(errors == 0) { strcat(buffArray, "\t \n"); } @@ -164,6 +251,17 @@ void PhyphoxBleExperiment::getFirstBytes(char *buffArray, const char *DEVICENAME } } } + + for(int i=0; iERROR.MESSAGE !=NULL){ + if(errors == 0){ + strcat(buffArray, "\t \n"); + } + SENSORS[i]->ERROR.getBytes(buffArray); + errors++; + } + } + if(errors>0) { strcat(buffArray,"\t\t\n"); //strcat(buffArray,"\" color=\"ff0000\">\n"); @@ -212,7 +310,4 @@ void PhyphoxBleExperiment::getLastBytes(char *buffArray){ //close strcat(buffArray, ""); -} - - - +} \ No newline at end of file diff --git a/src/exportSet.cpp b/src/exportSet.cpp index 2778d88..d97122f 100644 --- a/src/exportSet.cpp +++ b/src/exportSet.cpp @@ -1,4 +1,5 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" void PhyphoxBleExperiment::ExportSet::addElement(Element& e) { @@ -12,24 +13,19 @@ void PhyphoxBleExperiment::ExportSet::addElement(Element& e) } void PhyphoxBleExperiment::ExportSet::setLabel(const char *l){ - memset(&LABEL[0], 0, sizeof(LABEL)); - strcat(LABEL, " name=\""); - strcat(LABEL, l); - strcat(LABEL, "\""); + copyToMem(&LABEL, (" name=\"" + std::string(l) + "\"").c_str()); } void PhyphoxBleExperiment::ExportSet::setXMLAttribute(const char *xml){ - memset(&XMLAttribute[0], 0, sizeof(XMLAttribute)); - strcat(XMLAttribute, " "); - strcat(XMLAttribute, xml); + copyToMem(&XMLAttribute, (" " + std::string(xml)).c_str()); } void PhyphoxBleExperiment::ExportSet::getBytes(char *buffArray) { strcat(buffArray, "\t\n"); //loop over elements diff --git a/src/exportdata.cpp b/src/exportdata.cpp index 1494155..b23442d 100644 --- a/src/exportdata.cpp +++ b/src/exportdata.cpp @@ -1,32 +1,28 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" void PhyphoxBleExperiment::ExportData::setDatachannel(int d){ - sprintf(BUFFER, "CH%d", d); + char tmp[20]; + sprintf(tmp, "CH%d", d); + copyToMem(&BUFFER, tmp); } void PhyphoxBleExperiment::ExportData::setXMLAttribute(const char *xml){ - memset(&XMLAttribute[0], 0, sizeof(XMLAttribute)); - strcat(XMLAttribute," "); - strcat(XMLAttribute, xml); + copyToMem(&XMLAttribute, (" " + std::string(xml)).c_str()); } -void PhyphoxBleExperiment::ExportData::getBytes(char *buffArray) +void PhyphoxBleExperiment::ExportData::setLabel(const char *l) { - - strcat(buffArray,"\t\t"); - strcat(buffArray, BUFFER); - strcat(buffArray, "\n"); - + copyToMem(&LABEL, (std::string(l)).c_str()); } -void PhyphoxBleExperiment::ExportData::setLabel(const char *l) +void PhyphoxBleExperiment::ExportData::getBytes(char *buffArray) { - //ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(l, 41, "setLabel") : ERROR; - memset(&LABEL[0], 0, sizeof(LABEL)); - strcat(LABEL, " name=\""); - strcat(LABEL, l); - strcat(LABEL, "\""); + strcat(buffArray,"\t\t"); + if (!BUFFER) {strcat(buffArray,"CH1");} else {strcat(buffArray,BUFFER);} + strcat(buffArray, "\n"); + } \ No newline at end of file diff --git a/src/graph.cpp b/src/graph.cpp index 828168f..74686c8 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -1,97 +1,260 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" +#include void PhyphoxBleExperiment::Graph::setUnitX(const char *ux){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(ux, 5, "setUnitX") : ERROR; - memset(&UNITX[0], 0, sizeof(UNITX)); - strcat(UNITX, " unitX=\""); - strcat(UNITX, ux); - strcat(UNITX, "\""); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(ux, 5, "setUnitX") : ERROR; + copyToMem(&UNITX, (std::string(ux)).c_str()); } void PhyphoxBleExperiment::Graph::setUnitY(const char *uy){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(uy, 5, "setUnitY") : ERROR; - memset(&UNITY[0], 0, sizeof(UNITY)); - strcat(UNITY, " unitY=\""); - strcat(UNITY, uy); - strcat(UNITY, "\""); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(uy, 5, "setUnitY") : ERROR; + copyToMem(&UNITY, (std::string(uy)).c_str()); } void PhyphoxBleExperiment::Graph::setLabelX(const char *lx){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(lx, 20, "setLabelX") : ERROR; - memset(&LABELX[0], 0, sizeof(LABELX)); - strcat(LABELX, " labelX=\""); - strcat(LABELX, lx); - strcat(LABELX, "\""); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(lx, 20, "setLabelX") : ERROR; + copyToMem(&LABELX, (std::string(lx)).c_str()); } void PhyphoxBleExperiment::Graph::setLabelY(const char *ly){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(ly, 20, "setLabelX") : ERROR; - memset(&LABELY[0], 0, sizeof(LABELY)); - strcat(LABELY, " labelY=\""); - strcat(LABELY, ly); - strcat(LABELY, "\""); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(ly, 20, "setLabelY") : ERROR; + copyToMem(&LABELY, (std::string(ly)).c_str()); } + void PhyphoxBleExperiment::Graph::setColor(const char *c){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkHex(c, "setColor") : ERROR; - memset(&COLOR[0], 0, sizeof(COLOR)); - strcat(COLOR, " color=\""); - strcat(COLOR, c); - strcat(COLOR, "\""); + FIRSTSUBGRAPH.setColor(c); +} + +void PhyphoxBleExperiment::Graph::setLinewidth(float w){ + FIRSTSUBGRAPH.setLinewidth(w); } void PhyphoxBleExperiment::Graph::setXPrecision(int px){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkUpper(px, 9999, "setXPrecision") : ERROR; - sprintf(XPRECISION, " xPrecision=\"%i\"", px); + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(px, 9999, "setXPrecision") : ERROR; + char tmp[20]; + sprintf(tmp, "%i", px); + copyToMem(&XPRECISION, tmp); } void PhyphoxBleExperiment::Graph::setYPrecision(int py){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkUpper(py, 9999, "setYPrecision") : ERROR; - sprintf(YPRECISION, " yPrecision=\"%i\"", py); + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(py, 9999, "setYPrecision") : ERROR; + char tmp[20]; + sprintf(tmp, "%i", py); + copyToMem(&YPRECISION, tmp); +} + +void PhyphoxBleExperiment::Graph::setTimeOnX(bool b){ + char tmp[10]; + if(b){ + sprintf(tmp, "true"); + }else{ + sprintf(tmp, "false"); + } + copyToMem(&TIMEONX, tmp); +} + +void PhyphoxBleExperiment::Graph::setTimeOnY(bool b){ + char tmp[10]; + if(b){ + sprintf(tmp, "true"); + }else{ + sprintf(tmp, "false"); + } + copyToMem(&TIMEONY, tmp); +} + +void PhyphoxBleExperiment::Graph::setSystemTime(bool b){ + char tmp[10]; + if(b){ + sprintf(tmp, "true"); + }else{ + sprintf(tmp, "false"); + } + copyToMem(&SYSTEMTIME, tmp); } void PhyphoxBleExperiment::Graph::setChannel(int x, int y) { - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkUpper(x, numberOfChannels, "setChannel") : ERROR; - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkUpper(y, numberOfChannels, "setChannel") : ERROR; - sprintf(INPUTX, "CH%i", x); - sprintf(INPUTY, "CH%i", y); + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(x, numberOfChannels, "setChannel") : ERROR; + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(y, numberOfChannels, "setChannel") : ERROR; + + char tmpX[20]; + sprintf(tmpX, "CH%i", x); + copyToMem(&FIRSTSUBGRAPH.INPUTX, tmpX); + char tmpY[20]; + sprintf(tmpY, "CH%i", y); + copyToMem(&FIRSTSUBGRAPH.INPUTY, tmpY); + SUBGRAPHS[0]=&FIRSTSUBGRAPH; +} +void PhyphoxBleExperiment::Graph::addSubgraph(Subgraph& sg){ + for (int i = 0; i < phyphoxBleNChannel; i++){ + if(SUBGRAPHS[i]==nullptr){ + SUBGRAPHS[i] = &sg; + if(ERROR.MESSAGE==NULL){ + ERROR = sg.ERROR; + } + break; + } + } } void PhyphoxBleExperiment::Graph::setStyle(const char *s){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkStyle(s, "setStyle") : ERROR; - memset(&STYLE[0], 0, sizeof(STYLE)); - strcat(STYLE, " style=\""); - strcat(STYLE, s); - strcat(STYLE, "\""); + FIRSTSUBGRAPH.setStyle(s); +} + +void PhyphoxBleExperiment::Graph::setMinX(float value, const char * layout) { + /** + * Sets the min x value for the co-system. + * + * @param value The min x value. + * @param layout Choose between auto, extend and fixed. + */ + std::string layoutString; + layoutString.assign(layout); + std::ostringstream valueStringStream; + valueStringStream << value; + if(strcmp(layout, LAYOUT_AUTO) == 0 || strcmp(layout, LAYOUT_EXTEND) == 0 || strcmp(layout, LAYOUT_FIXED) == 0) { + copyToMem(&MINX, (" scaleMinX=\"" + layoutString + "\"" + " minX=\"" + valueStringStream.str() + "\"").c_str()); + } else { + ERROR = ERROR.MESSAGE == NULL ? err_checkLayout(layout, "setMinX") : ERROR; + } +} + +void PhyphoxBleExperiment::Graph::setMaxX(float value, const char * layout) { + /** + * Sets the min x value for the co-system. + * + * @param value The max x value. + * @param layout Choose between auto, extend and fixed. + */ + std::string layoutString; + layoutString.assign(layout); + std::ostringstream valueStringStream; + valueStringStream << value; + if(strcmp(layout, "auto") == 0 || strcmp(layout, "extend") == 0 || strcmp(layout, "fixed") == 0) { + copyToMem(&MAXX, (" scaleMaxX=\"" + layoutString + "\"" + " maxX=\"" + valueStringStream.str() + "\"").c_str()); + } else { + ERROR = ERROR.MESSAGE == NULL ? err_checkLayout(layout, "setMaxX") : ERROR; + } +} + +void PhyphoxBleExperiment::Graph::setMinY(float value, const char * layout) { + /** + * Sets the min x value for the co-system. + * + * @param value The min y value. + * @param layout Choose between auto, extend and fixed. + */ + std::string layoutString; + layoutString.assign(layout); + std::ostringstream valueStringStream; + valueStringStream << value; + if(strcmp(layout, "auto") == 0 || strcmp(layout, "extend") == 0 || strcmp(layout, "fixed") == 0) { + copyToMem(&MINY, (" scaleMinY=\"" + layoutString + "\"" + " minY=\"" + valueStringStream.str() + "\"").c_str()); + } else { + ERROR = ERROR.MESSAGE == NULL ? err_checkLayout(layout, "setMinY") : ERROR; + } +} +void PhyphoxBleExperiment::Graph::setMaxY(float value, const char * layout) { + /** + * Sets the min x value for the co-system. + * + * @param value The max y value. + * @param layout Choose between auto, extend and fixed. + */ + std::string layoutString; + layoutString.assign(layout); + std::ostringstream valueStringStream; + valueStringStream << value; + if(strcmp(layout, "auto") == 0 || strcmp(layout, "extend") == 0 || strcmp(layout, "fixed") == 0) { + copyToMem(&MAXY, (" scaleMaxY=\"" + layoutString + "\"" + " maxY=\"" + valueStringStream.str() + "\"").c_str()); + } else { + ERROR = ERROR.MESSAGE == NULL ? err_checkLayout(layout, "setMaxY") : ERROR; + } } void PhyphoxBleExperiment::Graph::setXMLAttribute(const char *xml){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(xml, 98, "setXMLAttribute") : ERROR; - memset(&XMLAttribute[0], 0, sizeof(XMLAttribute)); - strcat(XMLAttribute, " "); - strcat(XMLAttribute, xml); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(xml, 98, "setXMLAttribute") : ERROR; + copyToMem(&XMLAttribute, (" " + std::string(xml)).c_str()); } void PhyphoxBleExperiment::Graph::getBytes(char *buffArray) { strcat(buffArray,"\t\t\n"); - - strcat(buffArray, "\t\t\t"); - strcat(buffArray, INPUTX); - strcat(buffArray, "\n\t\t\t"); - strcat(buffArray, INPUTY); - strcat(buffArray, "\n\t\t\n"); -} + if (LABEL) { + strcat(buffArray," label=\""); + strcat(buffArray,LABEL); + strcat(buffArray,"\""); + }else{ + strcat(buffArray," label=\"myLabel\""); + } + if (LABELX){ + strcat(buffArray, " labelX=\""); + strcat(buffArray, LABELX); + strcat(buffArray, "\""); + } else { + strcat(buffArray," labelX=\"label x\""); + } + if (LABELY){ + strcat(buffArray, " labelY=\""); + strcat(buffArray, LABELY); + strcat(buffArray, "\""); + } else { + strcat(buffArray," labelY=\"label y\""); + } + + if(UNITX){ + strcat(buffArray, " unitX=\""); + strcat(buffArray, UNITX); + strcat(buffArray, "\""); + } + if(UNITY){ + strcat(buffArray, " unitY=\""); + strcat(buffArray, UNITY); + strcat(buffArray, "\""); + } + if (XPRECISION){ + strcat(buffArray," xPrecision=\""); + strcat(buffArray,XPRECISION); + strcat(buffArray,"\""); + } + if (YPRECISION){ + strcat(buffArray," yPrecision=\""); + strcat(buffArray,YPRECISION); + strcat(buffArray,"\""); + } + if (MINX) {strcat(buffArray,MINX);} + if (MAXX) {strcat(buffArray,MAXX);} + if (MINY) {strcat(buffArray,MINY);} + if (MAXY) {strcat(buffArray,MAXY);} + if (XMLAttribute) {strcat(buffArray,XMLAttribute);} + + if(TIMEONX){ + strcat(buffArray," timeOnX=\""); + strcat(buffArray,TIMEONX); + strcat(buffArray,"\""); + } + if(TIMEONY){ + strcat(buffArray," timeOnY=\""); + strcat(buffArray,TIMEONY); + strcat(buffArray,"\""); + } + if(SYSTEMTIME){ + strcat(buffArray," systemTime=\""); + strcat(buffArray,SYSTEMTIME); + strcat(buffArray,"\""); + } + + strcat(buffArray,">"); + + for(int i=0;igetBytes(buffArray); + } + } + + strcat(buffArray, "\n\t\t\n"); + +} \ No newline at end of file diff --git a/src/infoField.cpp b/src/infoField.cpp index 1fc4f9b..a9ada45 100644 --- a/src/infoField.cpp +++ b/src/infoField.cpp @@ -1,37 +1,36 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" void PhyphoxBleExperiment::InfoField::setInfo(const char *i) { - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(i, 191, "setInfo") : ERROR; - memset(&INFO[0], 0, sizeof(INFO)); - strcat(INFO, " label=\""); - strcat(INFO, i); - strcat(INFO, "\""); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(i, 191, "setInfo") : ERROR; + copyToMem(&INFO, (std::string(i)).c_str()); } void PhyphoxBleExperiment::InfoField::setColor(const char *c) { - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkHex(c, "setColor") : ERROR; - memset(&COLOR[0], 0, sizeof(COLOR)); - strcat(COLOR, " color=\""); - strcat(COLOR, c); - strcat(COLOR, "\""); + ERROR = ERROR.MESSAGE == NULL ? err_checkHex(c, "setColor") : ERROR; + copyToMem(&COLOR, (" color=\"" + std::string(c) + "\"").c_str()); } -void PhyphoxBleExperiment::InfoField::setXMLAttribute(const char *w){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(w, 98, "setXMLAttribute") : ERROR; - memset(&XMLAttribute[0], 0, sizeof(XMLAttribute)); - strcat(XMLAttribute, " "); - strcat(XMLAttribute, w); +void PhyphoxBleExperiment::InfoField::setXMLAttribute(const char *xml){ + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(xml, 98, "setXMLAttribute") : ERROR; + copyToMem(&XMLAttribute, (" " + std::string(xml)).c_str()); } void PhyphoxBleExperiment::InfoField::getBytes(char *buffArray) { strcat(buffArray,"\t\t\n"); strcat(buffArray,"\t\t\n"); diff --git a/src/phyphoxBLE_ESP32.cpp b/src/phyphoxBLE_ESP32.cpp index 4d62edb..58722a0 100644 --- a/src/phyphoxBLE_ESP32.cpp +++ b/src/phyphoxBLE_ESP32.cpp @@ -7,9 +7,10 @@ //init statics uint8_t PhyphoxBLE::data_package[20] = {0}; void (*PhyphoxBLE::configHandler)() = nullptr; -uint8_t storage[64000]; +void (*PhyphoxBLE::experimentEventHandler)() = nullptr; +uint8_t storage[16000]; //uint8_t *storage = (uint8_t*) malloc(8000 * sizeof(char)); -uint8_t *PhyphoxBLE::EXPARRAY=storage; +char *PhyphoxBLE::EXPARRAY=(char*)storage; uint8_t* PhyphoxBLE::p_exp = nullptr; size_t PhyphoxBLE::expLen = 0; HardwareSerial* PhyphoxBLE::printer =nullptr; @@ -19,8 +20,10 @@ BLEService *PhyphoxBLE::phyphoxExperimentService; BLEService *PhyphoxBLE::phyphoxDataService; BLEDescriptor *PhyphoxBLE::myExperimentDescriptor; BLEDescriptor *PhyphoxBLE::myDataDescriptor; +BLEDescriptor *PhyphoxBLE::myEventDescriptor; BLEDescriptor *PhyphoxBLE::myConfigDescriptor; BLECharacteristic *PhyphoxBLE::dataCharacteristic; +BLECharacteristic *PhyphoxBLE::eventCharacteristic; BLECharacteristic *PhyphoxBLE::experimentCharacteristic; BLECharacteristic *PhyphoxBLE::configCharacteristic; BLEAdvertising *PhyphoxBLE::myAdvertising; @@ -32,7 +35,12 @@ uint16_t PhyphoxBLE::maxConInterval = 24; //30ms uint16_t PhyphoxBLE::slaveLatency = 0; uint16_t PhyphoxBLE::timeout = 50; uint16_t PhyphoxBLE::currentConnections=0; +bool PhyphoxBLE::isSubscribed=false; +uint8_t PhyphoxBLE::eventData[17]={0}; +int64_t PhyphoxBLE::experimentTime = NULL; +int64_t PhyphoxBLE::systemTime = NULL; +uint8_t PhyphoxBLE::eventType = NULL; uint16_t PhyphoxBLE::MTU = 20; uint16_t PhyphoxBleExperiment::MTU = 20; @@ -56,6 +64,34 @@ class MyExpCallback: public BLEDescriptorCallbacks { }; }; +class MyDataCallback: public BLEDescriptorCallbacks { + + public: + MyDataCallback(){}; + + private: + + void onWrite(BLEDescriptor* pDescriptor){ + uint8_t* rxValue = pDescriptor->getValue(); + + if(pDescriptor->getLength() > 0){ + PhyphoxBLE::isSubscribed=true; + } + }; + }; + +class MyEventCallback: public BLECharacteristicCallbacks { + + public: + MyEventCallback(){}; + + private: + + void onWrite(BLECharacteristic *pCharacteristic) { + PhyphoxBLE::eventCharacteristicHandler(); + }; + }; + class MyCharCallback: public BLECharacteristicCallbacks { public: MyCharCallback(){}; @@ -80,20 +116,30 @@ class MyServerCallbacks: public BLEServerCallbacks { }; void PhyphoxBLE::configHandlerDebug(){ - if(configHandler!=nullptr){ (*configHandler)(); - } - - + } +} + +void PhyphoxBLE::eventCharacteristicHandler(){ + uint8_t* data = eventCharacteristic->getData(); + memcpy(&eventData[0],data,17); + int64_t et,st; + memcpy(&et,data+1,8); + memcpy(&st,data+1+8,8); + PhyphoxBLE::eventType = eventData[0]; + PhyphoxBLE::systemTime = swap_int64(st); + PhyphoxBLE::experimentTime = swap_int64(et); + if(experimentEventHandler!=nullptr){ + (*experimentEventHandler)(); + } } void PhyphoxBLE::setMTU(uint16_t mtuSize) { BLEDevice::setMTU(mtuSize+3); //user mtu size + 3 for overhead PhyphoxBLE::MTU = mtuSize; - PhyphoxBleExperiment::MTU = mtuSize; - + PhyphoxBleExperiment::MTU = mtuSize; } void PhyphoxBLE::start(const char* DEVICE_NAME, uint8_t* exp_pointer, size_t len){ @@ -126,7 +172,12 @@ void PhyphoxBLE::start(const char * DEVICE_NAME) PhyphoxBleExperiment::Graph firstGraph; //Create graph which will plot random numbers over time firstGraph.setChannel(0,1); - firstView.addElement(firstGraph); + //Value + PhyphoxBleExperiment::Value valueField; + valueField.setChannel(1); + + firstView.addElement(firstGraph); + firstView.addElement(valueField); defaultExperiment.addView(firstView); addExperiment(defaultExperiment); @@ -143,6 +194,10 @@ void PhyphoxBLE::start(const char * DEVICE_NAME) BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY ); + eventCharacteristic = phyphoxExperimentService->createCharacteristic( + phyphoxBleEventCharacteristicUUID, + BLECharacteristic::PROPERTY_WRITE + ); phyphoxDataService = myServer->createService(phyphoxBleDataServiceUUID); @@ -163,16 +218,20 @@ void PhyphoxBLE::start(const char * DEVICE_NAME) myExperimentDescriptor = new BLE2902(); myDataDescriptor = new BLE2902(); + myEventDescriptor = new BLE2902(); myConfigDescriptor = new BLE2902(); myExperimentDescriptor->setCallbacks(new MyExpCallback()); - + myDataDescriptor->setCallbacks(new MyDataCallback()); + eventCharacteristic->setCallbacks(new MyEventCallback()); + configCharacteristic->setCallbacks(new MyCharCallback()); + dataCharacteristic->addDescriptor(myDataDescriptor); experimentCharacteristic->addDescriptor(myExperimentDescriptor); + eventCharacteristic->addDescriptor(myEventDescriptor); configCharacteristic->addDescriptor(myConfigDescriptor); - - configCharacteristic->setCallbacks(new MyCharCallback()); + phyphoxExperimentService->start(); phyphoxDataService->start(); @@ -271,6 +330,36 @@ void PhyphoxBLE::read(float& f) uint8_t* data = configCharacteristic->getData(); memcpy(&f,data,4); } +void PhyphoxBLE::read(float& f1, float& f2) +{ + uint8_t* data = configCharacteristic->getData(); + memcpy(&f1,data,4); + memcpy(&f2,data+4,4); +} +void PhyphoxBLE::read(float& f1, float& f2, float& f3) +{ + uint8_t* data = configCharacteristic->getData(); + memcpy(&f1,data,4); + memcpy(&f2,data+4,4); + memcpy(&f3,data+8,4); +} +void PhyphoxBLE::read(float& f1, float& f2, float& f3, float& f4) +{ + uint8_t* data = configCharacteristic->getData(); + memcpy(&f1,data,4); + memcpy(&f2,data+4,4); + memcpy(&f3,data+8,4); + memcpy(&f4,data+12,4); +} +void PhyphoxBLE::read(float& f1, float& f2, float& f3, float& f4, float& f5) +{ + uint8_t* data = configCharacteristic->getData(); + memcpy(&f1,data,4); + memcpy(&f2,data+4,4); + memcpy(&f3,data+8,4); + memcpy(&f4,data+12,4); + memcpy(&f5,data+16,4); +} void PhyphoxBLE::when_subscription_received() @@ -330,37 +419,20 @@ void PhyphoxBLE::when_subscription_received() } void PhyphoxBLE::addExperiment(PhyphoxBleExperiment& exp) { - char buffer[2500] =""; - uint16_t length = 0; - - exp.getFirstBytes(buffer, deviceName); - memcpy(&EXPARRAY[length],&buffer[0],strlen(buffer)); - length += strlen(buffer); - memset(&(buffer[0]), NULL, strlen(buffer)); - - for(uint8_t i=0;iprint(CHAR); - } - } - #endif + exp.getFirstBytes(EXPARRAY, deviceName); + for(uint8_t i=0;iprintln(""); + for(int i =0; iprint(CHAR); + } + printer->println(""); +} + #endif diff --git a/src/phyphoxBLE_ESP32.h b/src/phyphoxBLE_ESP32.h index 5de7f94..1d1b71b 100644 --- a/src/phyphoxBLE_ESP32.h +++ b/src/phyphoxBLE_ESP32.h @@ -24,9 +24,11 @@ class PhyphoxBLE static BLEService *phyphoxExperimentService; static BLEDescriptor *myExperimentDescriptor; static BLEDescriptor *myDataDescriptor; + static BLEDescriptor *myEventDescriptor; static BLEDescriptor *myConfigDescriptor; static BLECharacteristic *dataCharacteristic; static BLECharacteristic *experimentCharacteristic; + static BLECharacteristic *eventCharacteristic; static BLECharacteristic *configCharacteristic; static BLEAdvertising *myAdvertising; @@ -37,7 +39,7 @@ class PhyphoxBLE static uint8_t* p_exp; //this pointer will point to the byte array which holds an experiment static TaskHandle_t TaskTransfer; - static uint8_t *EXPARRAY; + static char *EXPARRAY; static size_t expLen; //try o avoid this maybe use std::array or std::vector @@ -66,9 +68,18 @@ class PhyphoxBLE static void read(uint8_t*, unsigned int); static void read(float&); + static void read(float&, float&); + static void read(float&, float&, float&); + static void read(float&, float&, float&, float&); + static void read(float&, float&, float&, float&, float&); static void configHandlerDebug(); static void (*configHandler)(); + static void eventCharacteristicHandler(); + static void (*experimentEventHandler)(); + + static void printXML(HardwareSerial*); + static void setMTU(uint16_t); static uint16_t MTU; @@ -83,6 +94,12 @@ class PhyphoxBLE static uint16_t slaveLatency; static uint16_t timeout; static uint16_t currentConnections; + static bool isSubscribed; + + static uint8_t eventData[17]; + static int64_t experimentTime; + static int64_t systemTime; + static uint8_t eventType; }; diff --git a/src/phyphoxBLE_NRF52.cpp b/src/phyphoxBLE_NRF52.cpp index 7e1dbeb..3057011 100644 --- a/src/phyphoxBLE_NRF52.cpp +++ b/src/phyphoxBLE_NRF52.cpp @@ -7,6 +7,7 @@ const UUID PhyphoxBLE::experimentCharacteristicUUID = UUID(phyphoxBleExperimentC const UUID PhyphoxBLE::phyphoxDataServiceUUID = UUID(phyphoxBleDataServiceUUID); const UUID PhyphoxBLE::dataCharacteristicUUID = UUID(phyphoxBleDataCharacteristicUUID); const UUID PhyphoxBLE::configCharacteristicUUID = UUID(phyphoxBleConfigCharacteristicUUID); +const UUID PhyphoxBLE::eventCharacteristicUUID = UUID(phyphoxBleEventCharacteristicUUID); uint16_t PhyphoxBleExperiment::MTU = 20; @@ -17,6 +18,10 @@ Thread PhyphoxBLE::transferExpThread; uint8_t PhyphoxBLE::data_package[20] = {0}; uint8_t PhyphoxBLE::config_package[CONFIGSIZE] = {0}; +uint8_t PhyphoxBLE::eventData[17] = {0}; +int64_t PhyphoxBLE::experimentTime = NULL; +int64_t PhyphoxBLE::systemTime = NULL; +uint8_t PhyphoxBLE::eventType = NULL; /*BLE stuff*/ BLE& bleInstance = BLE::Instance(BLE::DEFAULT_INSTANCE); @@ -26,6 +31,7 @@ uint8_t PhyphoxBLE::readValue[DATASIZE] = {0}; ReadWriteArrayGattCharacteristic PhyphoxBLE::dataCharacteristic{PhyphoxBLE::dataCharacteristicUUID, PhyphoxBLE::data_package, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY}; //Note: Use { } instead of () google most vexing parse ReadWriteArrayGattCharacteristic PhyphoxBLE::configCharacteristic{PhyphoxBLE::configCharacteristicUUID, PhyphoxBLE::config_package, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY}; +ReadWriteArrayGattCharacteristic PhyphoxBLE::eventCharacteristic{PhyphoxBLE::eventCharacteristicUUID, PhyphoxBLE::eventData, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY}; //Experiment Transfer ReadOnlyArrayGattCharacteristic PhyphoxBLE::experimentCharacteristic{PhyphoxBLE::experimentCharacteristicUUID, PhyphoxBLE::readValue, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY}; @@ -36,7 +42,7 @@ EventQueue PhyphoxBLE::transferQueue{32 * EVENTS_EVENT_SIZE}; PhyphoxBleEventHandler PhyphoxBLE::eventHandler(bleInstance); -GattCharacteristic* PhyphoxBLE::phyphoxCharacteristics[1] = {&PhyphoxBLE::experimentCharacteristic}; +GattCharacteristic* PhyphoxBLE::phyphoxCharacteristics[2] = {&PhyphoxBLE::experimentCharacteristic,&PhyphoxBLE::eventCharacteristic}; GattService PhyphoxBLE::phyphoxService{PhyphoxBLE::phyphoxExperimentServiceUUID, PhyphoxBLE::phyphoxCharacteristics, sizeof(PhyphoxBLE::phyphoxCharacteristics) / sizeof(GattCharacteristic *)}; GattCharacteristic* PhyphoxBLE::phyphoxDataCharacteristics[2] = {&PhyphoxBLE::dataCharacteristic, &PhyphoxBLE::configCharacteristic}; @@ -44,12 +50,14 @@ GattService PhyphoxBLE::phyphoxDataService{PhyphoxBLE::phyphoxDataServiceUUID, P uint8_t* PhyphoxBLE::data = nullptr; //this pointer points to the data the user wants to write in the characteristic uint8_t* PhyphoxBLE::config =nullptr; +uint8_t* PhyphoxBLE::event =nullptr; uint8_t* PhyphoxBLE::p_exp = nullptr; //this pointer will point to the byte array which holds an experiment -uint8_t PhyphoxBLE::EXPARRAY[4096] = {0};// block some storage +char PhyphoxBLE::EXPARRAY[4096] = {0};// block some storage size_t PhyphoxBLE::expLen = 0; //try o avoid this maybe use std::array or std::vector void (*PhyphoxBLE::configHandler)() = nullptr; +void (*PhyphoxBLE::experimentEventHandler)() = nullptr; void PhyphoxBleEventHandler::onDisconnectionComplete(const ble::DisconnectionCompleteEvent &event) { @@ -101,6 +109,15 @@ void PhyphoxBLE::output(const uint32_t num) #endif +void PhyphoxBLE::printXML(HardwareSerial* printer){ + printer->println(""); + for(int i =0; iprint(CHAR); + } + printer->println(""); +} + void PhyphoxBLE::when_subscription_received(GattAttribute::Handle_t handle) @@ -122,10 +139,28 @@ void PhyphoxBLE::when_subscription_received(GattAttribute::Handle_t handle) } void PhyphoxBLE::configReceived(const GattWriteCallbackParams *params) { - if(configHandler != nullptr){ - transferQueue.call( configHandler ); + if(params->handle == configCharacteristic.getValueHandle()){ + if(configHandler != nullptr){ + transferQueue.call( configHandler ); + } + }else if (params->handle == eventCharacteristic.getValueHandle()) + { + uint16_t eventSize = 17; + ble.gattServer().read(eventCharacteristic.getValueHandle(), eventData, &eventSize); + int64_t et,st; + memcpy(&et,&eventData[0]+1,8); + memcpy(&st,&eventData[0]+1+8,8); + PhyphoxBLE::eventType = eventData[0]; + PhyphoxBLE::systemTime = swap_int64(st); + PhyphoxBLE::experimentTime = swap_int64(et); + if(experimentEventHandler != nullptr){ + transferQueue.call( experimentEventHandler ); + } + } + } + void PhyphoxBLE::transferExp() { BLE &ble = PhyphoxBLE::ble; @@ -137,7 +172,7 @@ void PhyphoxBLE::transferExp() #endif uint8_t header[20] = {0}; //20 byte as standard package size for ble transfer - const char phyphox[] = "phyphox"; + const char phyphox[] = "phyphox-Arduino"; uint32_t table[256]; phyphoxBleCrc32::generate_table(table); uint32_t checksum = phyphoxBleCrc32::update(table, 0, exp, exp_len); @@ -187,6 +222,7 @@ void PhyphoxBLE::bleInitComplete(BLE::InitializationCompleteCallbackContext* par ble.gattServer().onUpdatesEnabled(PhyphoxBLE::when_subscription_received); ble.gattServer().onDataWritten(PhyphoxBLE::configReceived); + ble.gap().setEventHandler(&PhyphoxBLE::eventHandler); uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; @@ -241,8 +277,8 @@ void PhyphoxBLE::start(const char* DEVICE_NAME, uint8_t* exp_pointer, size_t len if(exp_pointer != nullptr){ p_exp = exp_pointer; expLen = len; - }else{ - + }else if(p_exp==nullptr){ + PhyphoxBleExperiment defaultExperiment; //View @@ -256,7 +292,7 @@ void PhyphoxBLE::start(const char* DEVICE_NAME, uint8_t* exp_pointer, size_t len defaultExperiment.addView(firstView); addExperiment(defaultExperiment); - + } bleEventThread.start(callback(&queue, &EventQueue::dispatch_forever)); @@ -266,7 +302,7 @@ void PhyphoxBLE::start(const char* DEVICE_NAME, uint8_t* exp_pointer, size_t len } void PhyphoxBLE::start(uint8_t* exp_pointer, size_t len) { - start("phyphox", exp_pointer, len); + start("phyphox-Arduino", exp_pointer, len); } void PhyphoxBLE::start(const char* DEVICE_NAME) { @@ -275,7 +311,7 @@ void PhyphoxBLE::start(const char* DEVICE_NAME) { } void PhyphoxBLE::start() { - start("phyphox", nullptr, 0); + start("phyphox-Arduino", nullptr, 0); } void PhyphoxBLE::poll() { @@ -369,6 +405,45 @@ void PhyphoxBLE::read(float& f1) ble.gattServer().read(configCharacteristic.getValueHandle(), myConfig, &configSize); memcpy(&f1,&myConfig[0], 4); } +void PhyphoxBLE::read(float& f1, float& f2) +{ + uint16_t configSize = 8; + uint8_t myConfig[8]; + ble.gattServer().read(configCharacteristic.getValueHandle(), myConfig, &configSize); + memcpy(&f1,&myConfig[0],4); + memcpy(&f2,&myConfig[0]+4,4); +} +void PhyphoxBLE::read(float& f1, float& f2, float& f3) +{ + uint16_t configSize = 12; + uint8_t myConfig[12]; + ble.gattServer().read(configCharacteristic.getValueHandle(), myConfig, &configSize); + memcpy(&f1,&myConfig[0],4); + memcpy(&f2,&myConfig[0]+4,4); + memcpy(&f3,&myConfig[0]+8,4); +} +void PhyphoxBLE::read(float& f1, float& f2, float& f3, float& f4) +{ + uint16_t configSize = 16; + uint8_t myConfig[16]; + ble.gattServer().read(configCharacteristic.getValueHandle(), myConfig, &configSize); + memcpy(&f1,&myConfig[0],4); + memcpy(&f2,&myConfig[0]+4,4); + memcpy(&f3,&myConfig[0]+8,4); + memcpy(&f4,&myConfig[0]+12,4); +} +void PhyphoxBLE::read(float& f1, float& f2, float& f3, float& f4, float& f5) +{ + uint16_t configSize = 20; + uint8_t myConfig[20]; + ble.gattServer().read(configCharacteristic.getValueHandle(), myConfig, &configSize); + memcpy(&f1,&myConfig[0],4); + memcpy(&f2,&myConfig[0]+4,4); + memcpy(&f3,&myConfig[0]+8,4); + memcpy(&f4,&myConfig[0]+12,4); + memcpy(&f5,&myConfig[0]+16,4); +} + void PhyphoxBLE::read(uint8_t *arrayPointer, unsigned int arraySize) { uint16_t myArraySize = arraySize; @@ -378,28 +453,18 @@ void PhyphoxBLE::read(uint8_t *arrayPointer, unsigned int arraySize) void PhyphoxBLE::addExperiment(PhyphoxBleExperiment& exp) { - char buffer[2000] =""; - uint16_t length = 0; - - exp.getFirstBytes(buffer, deviceName); - memcpy(&EXPARRAY[length],&buffer[0],strlen(buffer)); - length += strlen(buffer); - memset(&(buffer[0]), NULL, strlen(buffer)); - - for(uint8_t i=0;i dataCharacteristic; //Note: Use { } instead of () google most vexing parse static uint8_t readValue[DATASIZE]; + static ReadWriteArrayGattCharacteristic eventCharacteristic; static ReadWriteArrayGattCharacteristic configCharacteristic; static ReadOnlyArrayGattCharacteristic experimentCharacteristic; @@ -79,6 +82,7 @@ class PhyphoxBLE static void bleInitComplete(BLE::InitializationCompleteCallbackContext*); static void when_subscription_received(GattAttribute::Handle_t); static void configReceived(const GattWriteCallbackParams *params); + static void eventReceived(const GattWriteCallbackParams *params); //helper functon that runs in the thread ble_server //static void waitForEvent(); @@ -96,12 +100,13 @@ class PhyphoxBLE #endif static uint8_t* data; //this pointer points to the data the user wants to write in the characteristic static uint8_t* config; + static uint8_t* event; static uint8_t* p_exp; //this pointer will point to the byte array which holds an experiment public: - static uint8_t EXPARRAY[4096];// block some storage + static char EXPARRAY[4096];// block some storage static size_t expLen; //try o avoid this maybe use std::array or std::vector static inline uint16_t minConInterval = 6; //7.5ms @@ -112,6 +117,9 @@ class PhyphoxBLE static inline uint16_t currentConnections = 0; static void (*configHandler)(); + static void (*experimentEventHandler)(); + + static void printXML(HardwareSerial*); static void poll(); static void poll(int timeout); @@ -129,8 +137,17 @@ class PhyphoxBLE static void write(float&, float&); static void read(uint8_t*, unsigned int); static void read(float&); + static void read(float&, float&); + static void read(float&, float&, float&); + static void read(float&, float&, float&, float&); + static void read(float&, float&, float&, float&, float&); static void addExperiment(PhyphoxBleExperiment&); + + static int64_t experimentTime; + static int64_t systemTime; + static uint8_t eventType; + #ifndef NDEBUG static void begin(HardwareSerial*); //for debug purpose static void output(const char*); //for debug purpose diff --git a/src/phyphoxBLE_NanoIOT.cpp b/src/phyphoxBLE_NanoIOT.cpp index 08898fd..d214e6b 100644 --- a/src/phyphoxBLE_NanoIOT.cpp +++ b/src/phyphoxBLE_NanoIOT.cpp @@ -1,4 +1,4 @@ -#ifdef ARDUINO_SAMD_NANO_33_IOT +#if defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_UNOR4_WIFI) #include "phyphoxBLE_NanoIOT.h" #include "Arduino.h" @@ -7,6 +7,7 @@ BLEService PhyphoxBLE::phyphoxExperimentService{phyphoxBleExperimentServiceUUID}; // create service BLECharacteristic PhyphoxBLE::experimentCharacteristic{phyphoxBleExperimentCharacteristicUUID, BLERead | BLEWrite| BLENotify, 20, false}; BLECharacteristic PhyphoxBLE::controlCharacteristic{phyphoxBleExperimentControlCharacteristicUUID, BLERead | BLEWrite| BLENotify, 20, false}; +BLECharacteristic PhyphoxBLE::eventCharacteristic{phyphoxBleEventCharacteristicUUID, BLERead | BLEWrite| BLENotify, 20, false}; BLEService PhyphoxBLE::phyphoxDataService{phyphoxBleDataServiceUUID}; // create service BLECharacteristic PhyphoxBLE::dataCharacteristic{phyphoxBleDataCharacteristicUUID, BLERead | BLEWrite | BLENotify, 20, false}; @@ -20,13 +21,22 @@ uint16_t PhyphoxBLE::timeout = 50; uint16_t PhyphoxBLE::MTU = 20; uint16_t PhyphoxBleExperiment::MTU = 20; +int64_t PhyphoxBLE::experimentTime = NULL; +int64_t PhyphoxBLE::systemTime = NULL; +uint8_t PhyphoxBLE::eventType = NULL; + uint8_t* PhyphoxBLE::data = nullptr; //this pointer points to the data the user wants to write in the characteristic uint8_t* PhyphoxBLE::p_exp = nullptr; //this pointer will point to the byte array which holds an experiment size_t PhyphoxBLE::expLen = 0; //try o avoid this maybe use std::array or std::vector -uint8_t PhyphoxBLE::EXPARRAY[4000] = {0};// block some storage +const int maxExperimentSize = 6000; +uint8_t storage[maxExperimentSize]; +uint8_t PhyphoxBLE::eventData[17]={0}; +//uint8_t eventData[17]; +char *PhyphoxBLE::EXPARRAY=(char*)storage; void(*PhyphoxBLE::configHandler)() = nullptr; +void(*PhyphoxBLE::experimentEventHandler)() = nullptr; void PhyphoxBLE::start(const char* DEVICE_NAME, uint8_t* exp_pointer, size_t len){ p_exp = exp_pointer; @@ -45,8 +55,9 @@ void PhyphoxBLE::start(const char* DEVICE_NAME) deviceName = DEVICE_NAME; controlCharacteristic.setEventHandler(BLEWritten, controlCharacteristicWritten); + eventCharacteristic.setEventHandler(BLEWritten, eventCharacteristicWritten); configCharacteristic.setEventHandler(BLEWritten, configCharacteristicWritten); - + if(p_exp == nullptr){ PhyphoxBleExperiment defaultExperiment; @@ -73,6 +84,7 @@ void PhyphoxBLE::start(const char* DEVICE_NAME) // add the characteristics to the service phyphoxExperimentService.addCharacteristic(experimentCharacteristic); phyphoxExperimentService.addCharacteristic(controlCharacteristic); + phyphoxExperimentService.addCharacteristic(eventCharacteristic); phyphoxDataService.addCharacteristic(configCharacteristic); phyphoxDataService.addCharacteristic(dataCharacteristic); @@ -114,30 +126,58 @@ void PhyphoxBLE::read(float& f) memcpy(&f,&readDATA[0],4); } +void PhyphoxBLE::read(float& f1, float& f2) +{ + uint8_t readDATA[8]; + configCharacteristic.readValue(readDATA, 8); + memcpy(&f1,readDATA,4); + memcpy(&f2,readDATA+4,4); +} +void PhyphoxBLE::read(float& f1, float& f2, float& f3) +{ + uint8_t readDATA[12]; + configCharacteristic.readValue(readDATA, 12); + memcpy(&f1,readDATA,4); + memcpy(&f2,readDATA+4,4); + memcpy(&f3,readDATA+8,4); +} +void PhyphoxBLE::read(float& f1, float& f2, float& f3, float& f4) +{ + uint8_t readDATA[16]; + configCharacteristic.readValue(readDATA, 16); + memcpy(&f1,readDATA,4); + memcpy(&f2,readDATA+4,4); + memcpy(&f3,readDATA+8,4); + memcpy(&f4,readDATA+12,4); +} +void PhyphoxBLE::read(float& f1, float& f2, float& f3, float& f4, float& f5) +{ + uint8_t readDATA[20]; + configCharacteristic.readValue(readDATA, 20); + memcpy(&f1,readDATA,4); + memcpy(&f2,readDATA+4,4); + memcpy(&f3,readDATA+8,4); + memcpy(&f4,readDATA+12,4); + memcpy(&f5,readDATA+16,4); +} + void PhyphoxBLE::addExperiment(PhyphoxBleExperiment& exp) { - char buffer[2000] =""; - uint16_t length = 0; + memset(EXPARRAY,0,maxExperimentSize); + + exp.getFirstBytes(EXPARRAY, deviceName); - exp.getFirstBytes(buffer, deviceName); - memcpy(&EXPARRAY[length],&buffer[0],strlen(buffer)); - length += strlen(buffer); - memset(&(buffer[0]), NULL, strlen(buffer)); for(uint8_t i=0;iprintln(""); + for(int i =0; iprint(CHAR); + } + printer->println(""); +} #endif diff --git a/src/phyphoxBLE_NanoIOT.h b/src/phyphoxBLE_NanoIOT.h index ddea381..77b84d2 100644 --- a/src/phyphoxBLE_NanoIOT.h +++ b/src/phyphoxBLE_NanoIOT.h @@ -11,11 +11,13 @@ class PhyphoxBLE static uint8_t data_package[20]; static void controlCharacteristicWritten(BLEDevice, BLECharacteristic); + static void eventCharacteristicWritten(BLEDevice, BLECharacteristic); static void configCharacteristicWritten(BLEDevice, BLECharacteristic); static BLEService phyphoxExperimentService; static BLECharacteristic experimentCharacteristic; static BLECharacteristic controlCharacteristic; + static BLECharacteristic eventCharacteristic; static BLEService phyphoxDataService; static BLECharacteristic dataCharacteristic; @@ -26,7 +28,7 @@ class PhyphoxBLE static uint8_t* p_exp; //this pointer will point to the byte array which holds an experiment static size_t expLen; //try o avoid this maybe use std::array or std::vector - static uint8_t EXPARRAY[4000];// block some storage + static char *EXPARRAY; public: @@ -45,18 +47,32 @@ class PhyphoxBLE static void read(uint8_t*, unsigned int); static void read(float&); - + static void read(float&, float&); + static void read(float&, float&, float&); + static void read(float&, float&, float&, float&); + static void read(float&, float&, float&, float&, float&); static void poll(); static void poll(int timeout); static void(*configHandler)(); + static void(*experimentEventHandler)(); + static uint16_t minConInterval; static uint16_t maxConInterval; static uint16_t slaveLatency; static uint16_t timeout; static uint16_t MTU; + + static int64_t experimentTime; + static int64_t systemTime; + static uint8_t eventType; + + static uint8_t eventData[17]; + + static void printXML(HardwareSerial*); + }; diff --git a/src/phyphoxBle.h b/src/phyphoxBle.h index d609e9a..02da152 100644 --- a/src/phyphoxBle.h +++ b/src/phyphoxBle.h @@ -1,9 +1,12 @@ #ifndef PHYPHOXBLE #define PHYPHOXBLE +#include "Arduino.h" + static const char *phyphoxBleExperimentServiceUUID = "cddf0001-30f7-4671-8b43-5e40ba53514a"; static const char *phyphoxBleExperimentCharacteristicUUID = "cddf0002-30f7-4671-8b43-5e40ba53514a"; static const char *phyphoxBleExperimentControlCharacteristicUUID = "cddf0003-30f7-4671-8b43-5e40ba53514a"; +static const char *phyphoxBleEventCharacteristicUUID = "cddf0004-30f7-4671-8b43-5e40ba53514a"; static const char *phyphoxBleDataServiceUUID = "cddf1001-30f7-4671-8b43-5e40ba53514a"; static const char *phyphoxBleDataCharacteristicUUID = "cddf1002-30f7-4671-8b43-5e40ba53514a"; @@ -11,6 +14,33 @@ static const char *phyphoxBleConfigCharacteristicUUID = "cddf1003-30f7-4671-8b43 static const char *deviceName = "phyphox-Arduino"; +#define SENSOR_ACCELEROMETER "accelerometer" +#define SENSOR_ACCELEROMETER_WITHOUT_G "linear_acceleration" +#define SENSOR_GYROSCOPE "gyroscope" +#define SENSOR_MAGNETOMETER "magnetometer" +#define SENSOR_PRESSURE "pressure" +#define SENSOR_TEMPERATURE "temperature" +#define SENSOR_LIGHT "light" +#define SENSOR_HUMIDITY "humidity" +#define SENSOR_PROXIMITY "proximity" + +#define STYLE_DOTS "dots" +#define STYLE_LINES "lines" +#define STYLE_VBARS "vbars" +#define STYLE_HBARS "hbars" +#define STYLE_MAP "map" + +#define COLOR_RED "fe005d" +#define COLOR_BLUE "39a2ff" +#define COLOR_GREEN "2bfb4c" +#define COLOR_ORANGE "ff7e22" +#define COLOR_WHITE "ffffff" +#define COLOR_YELLOW "edf668" +#define COLOR_MAGENTA "eb46f4" + +#define LAYOUT_AUTO "auto" +#define LAYOUT_EXTEND "extend" +#define LAYOUT_FIXED "fixed" #ifndef CONFIGSIZE #define CONFIGSIZE 20 @@ -23,7 +53,7 @@ static const char *deviceName = "phyphox-Arduino"; #elif defined(ESP32) #include "phyphoxBLE_ESP32.h" -#elif defined(ARDUINO_SAMD_NANO_33_IOT) +#elif defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_UNOR4_WIFI) #include #include "phyphoxBLE_NanoIOT.h" #else @@ -65,5 +95,10 @@ struct phyphoxBleCrc32 } }; +static int64_t swap_int64( int64_t val ){ + val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL ); + val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL ); + return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL); +} #endif diff --git a/src/phyphoxBleExperiment.h b/src/phyphoxBleExperiment.h index cb878ee..9c2f055 100644 --- a/src/phyphoxBleExperiment.h +++ b/src/phyphoxBleExperiment.h @@ -1,11 +1,9 @@ #ifndef PHYPHOX_BLE_EXPERIMENT #define PHYPHOX_BLE_EXPERIMENT -#define phyphoxBleNViews 5 -#define phyphoxBleNElements 20 -#define phyphoxBleNExportSets 5 - #include +#include "copyToMem.h" +#include "defines.h" class PhyphoxBleExperiment { @@ -20,7 +18,7 @@ class PhyphoxBleExperiment { class Error { public: - char MESSAGE[35] = ""; + char* MESSAGE = NULL; void getBytes(char *); }; @@ -31,6 +29,9 @@ class PhyphoxBleExperiment { virtual Error err_checkUpper(int, int, const char *); virtual Error err_checkHex(const char *, const char *); virtual Error err_checkStyle(const char *, const char *); + virtual Error err_checkLayout(const char *, const char *); + virtual Error err_checkComponent(const char *, const char *); + virtual Error err_checkSensor(const char *, const char *); }; class Element : public Errorhandler { @@ -42,7 +43,7 @@ class PhyphoxBleExperiment { int typeID = 0; - char LABEL[50] = " label=\"label\""; + char* LABEL = NULL; Error ERROR; @@ -52,28 +53,65 @@ class PhyphoxBleExperiment { private: }; + + class Graph : public Element { public: + + class Subgraph : public Errorhandler + { + public: + Subgraph() = default; + Subgraph(const Subgraph &) = delete; + Subgraph &operator=(const Subgraph &) = delete; + ~Subgraph() = default; + + char* INPUTX = NULL; + char* INPUTY = NULL; + char* COLOR = NULL; + char* WIDTH = NULL; + char* STYLE = NULL; + bool isActive = false; + + void setColor(const char *); + void setStyle(const char *); + void setLinewidth(float w); + void setChannel(int, int); + void getBytes(char *); + + Error ERROR; + private: + }; + Graph() = default; Graph(const Graph &) = delete; Graph &operator=(const Graph &) = delete; ~Graph() = default; - char UNITX[14] = ""; - char UNITY[14] = ""; - char LABELX[30] = " labelX=\"label x\""; - char LABELY[30] = " labelY=\"label y\""; - char COLOR[17] = ""; - char XPRECISION[20] = ""; - char YPRECISION[20] = ""; + char* UNITX = NULL; + char* UNITY = NULL; + char* LABELX = NULL; + char* LABELY = NULL; + char* XPRECISION = NULL; + char* YPRECISION = NULL; + char* MINX = NULL; + char* MAXX = NULL; + char* MINY = NULL; + char* MAXY = NULL; - char INPUTX[5] = "CH0"; - char INPUTY[5] = "CH1"; + char* TIMEONX = NULL; + char* TIMEONY = NULL; + + char* SYSTEMTIME = NULL; - char STYLE[17] = ""; + char* INPUTX = NULL; + char* INPUTY = NULL; - char XMLAttribute[25] = ""; + Subgraph *SUBGRAPHS[phyphoxBleNChannel]={nullptr}; + Subgraph FIRSTSUBGRAPH; + + char* XMLAttribute = NULL; void setUnitX(const char *); void setUnitY(const char *); @@ -81,9 +119,20 @@ class PhyphoxBleExperiment { void setLabelY(const char *); void setXPrecision(int); void setYPrecision(int); - void setColor(const char *); + void setTimeOnX(bool); + void setTimeOnY(bool); + void setSystemTime(bool); + void setChannel(int, int); + void addSubgraph(Subgraph &); + void addChannel(int, int, const char*); void setStyle(const char *); + void setColor(const char *); + void setLinewidth(float w); + void setMinX(float, const char *); + void setMaxX(float, const char *); + void setMinY(float, const char *); + void setMaxY(float, const char *); void setXMLAttribute(const char *); void phyphoxTimestamp(); @@ -105,8 +154,8 @@ class PhyphoxBleExperiment { void addElement(Element &); void setXMLAttribute(const char *); - char LABEL[50] = " label=\"label\""; - char XMLAttribute[25] = ""; + char* LABEL = NULL; + char* XMLAttribute = NULL; Element *ELEMENTS[phyphoxBleNElements] = {nullptr}; @@ -121,8 +170,9 @@ class PhyphoxBleExperiment { ExportData &operator=(const ExportData &) = delete; ~ExportData() = default; - char BUFFER[5] = "CH1"; - char XMLAttribute[1] = ""; + char* BUFFER = NULL; + char* LABEL = NULL; + char* XMLAttribute = NULL; void setDatachannel(int); void setXMLAttribute(const char *); void setLabel(const char *); @@ -144,13 +194,41 @@ class PhyphoxBleExperiment { void addElement(Element &); void setXMLAttribute(const char *); - char LABEL[50] = ""; - char XMLAttribute[25] = ""; + char* LABEL = NULL; + char* XMLAttribute = NULL; Element *ELEMENTS[phyphoxBleNExportSets] = {nullptr}; private: }; + class Sensor : public Errorhandler + { + public: + Sensor(){}; + Sensor(const Sensor &) = delete; + Sensor &operator=(const Sensor &) = delete; + ~Sensor() = default; + + void setType(const char *); + void setComponent(const char *); + void setAverage(bool); + void setRate(int); + void mapChannel(const char *, int); + void setXMLAttribute(const char *); + void getBytes(char *); + + char* TYPE = NULL; + char* CHANNEL[5] = {NULL}; + char* COMPONENT[5] = {NULL}; + char* RATE = NULL; + char* AVERAGE = NULL; + char* XMLAttribute = NULL; + + Error ERROR; + + private: + }; + class InfoField : public Element { public: @@ -164,9 +242,9 @@ class PhyphoxBleExperiment { void setXMLAttribute(const char *); void getBytes(char *); - char INFO[200] = ""; - char COLOR[17] = ""; - char XMLAttribute[25] = ""; + char* INFO = NULL; + char* COLOR = NULL; + char* XMLAttribute = NULL; private: }; @@ -184,9 +262,9 @@ class PhyphoxBleExperiment { void setXMLAttribute(const char *); void getBytes(char *); - char COLOR[17] = ""; - char HEIGHT[20] = " height=\"0.1\""; - char XMLAttribute[25] = ""; + char* COLOR = NULL; + char* HEIGHT = NULL; + char* XMLAttribute = NULL; private: }; @@ -206,11 +284,11 @@ class PhyphoxBleExperiment { void setChannel(int); void setXMLAttribute(const char *); - char PRECISION[15] = ""; - char UNIT[20] = ""; - char COLOR[17] = ""; - char INPUTVALUE[5] = "CH3"; - char XMLAttribute[25] = ""; + char* PRECISION = NULL; + char* UNIT = NULL; + char* COLOR = NULL; + char* INPUTVALUE = NULL; + char* XMLAttribute = NULL; private: }; @@ -230,11 +308,11 @@ class PhyphoxBleExperiment { void setChannel(int); void getBytes(char *); - char UNIT[20] = ""; - char SIGNED[17] = ""; - char DECIMAL[17] = ""; - char XMLAttribute[25] = ""; - char BUFFER[5] = "CH5"; + char* UNIT = NULL; + char* SIGNED = NULL; + char* DECIMAL = NULL; + char* XMLAttribute = NULL; + char* BUFFER = NULL; private: }; @@ -242,21 +320,28 @@ class PhyphoxBleExperiment { void setTitle(const char *); void setCategory(const char *); void setDescription(const char *); - void setConfig(const char *); + void setColor(const char *); + void setRepeating(const int); + // void setConfig(const char *); + void setSubscribeOnStart(bool); void getBytes(char *); void getFirstBytes(char *, const char *); void getViewBytes(char *, uint8_t, uint8_t); void getLastBytes(char *); void addView(View &); + void addSensor(Sensor &); void addExportSet(ExportSet &); - char TITLE[50] = "Arduino-Experiment"; - char CATEGORY[50] = "Arduino Experiments"; - char DESCRIPTION[500] = "An experiment created with the phyphox BLE library for Arduino-compatible micro controllers."; - char CONFIG[8] = "000000"; + char* TITLE = NULL; + char* CATEGORY = NULL; + char* DESCRIPTION = NULL; + char* COLOR = NULL; + // char* CONFIG = NULL; + char* SUBSCRIBEONSTART = NULL; View *VIEWS[phyphoxBleNViews] = {nullptr}; + Sensor *SENSORS[phyphoxBleNSensors] = {nullptr}; ExportSet *EXPORTSETS[phyphoxBleNExportSets] = {nullptr}; static int numberOfChannels; diff --git a/src/sensor.cpp b/src/sensor.cpp new file mode 100644 index 0000000..b835f6f --- /dev/null +++ b/src/sensor.cpp @@ -0,0 +1,80 @@ +#include "phyphoxBleExperiment.h" +#include "copyToMem.h" +#include + +void PhyphoxBleExperiment::Sensor::setType(const char *t) +{ + ERROR = ERROR.MESSAGE == NULL ? err_checkSensor(t, "setType") : ERROR; + copyToMem(&TYPE, (std::string(t)).c_str()); +} + +void PhyphoxBleExperiment::Sensor::mapChannel(const char *comp, int ch) +{ + for(int i=0;i<5;i++){ + if (COMPONENT[i]==NULL) + { + ERROR = ERROR.MESSAGE == NULL ? err_checkComponent(comp, "routeData") : ERROR; + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(ch,5, "routeData") : ERROR; + copyToMem(&COMPONENT[i], (std::string(comp)).c_str()); + std::ostringstream s; + s << ch; + std::string temp = s.str(); + copyToMem(&CHANNEL[i], ("CB"+temp).c_str()); + break; + } + } +} +void PhyphoxBleExperiment::Sensor::setAverage(bool b) +{ + if(b){ + copyToMem(&AVERAGE, "true"); + }else{ + copyToMem(&AVERAGE, "false"); + } +} + +void PhyphoxBleExperiment::Sensor::setRate(int r){ + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(r,100, "setRate") : ERROR; + std::ostringstream s; + s << r; + std::string temp = s.str(); + copyToMem(&RATE, (" rate=\""+temp+"\"").c_str()); +} + +void PhyphoxBleExperiment::Sensor::setXMLAttribute(const char *xml){ + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(xml, 98, "setXMLAttribute") : ERROR; + copyToMem(&XMLAttribute, (" " + std::string(xml)).c_str()); +} + +void PhyphoxBleExperiment::Sensor::getBytes(char *buffArray) +{ + if(ERROR.MESSAGE == NULL){ + strcat(buffArray,"\t\n"); + //route components + for (int i = 0; i < 5; i++){ + if(CHANNEL[i]!=NULL && COMPONENT[i]!=NULL){ + strcat(buffArray,"\t\t"); + strcat(buffArray,CHANNEL[i]); + strcat(buffArray,"\n"); + } + } + strcat(buffArray,"\t\n"); + } + +} \ No newline at end of file diff --git a/src/separator.cpp b/src/separator.cpp index 25ef8de..be7a8e6 100644 --- a/src/separator.cpp +++ b/src/separator.cpp @@ -1,37 +1,35 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" void PhyphoxBleExperiment::Separator::setHeight(float h) { - char tmp[10]; - sprintf(tmp, "%f", h);; - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(tmp, 10, "setHeight") : ERROR; - sprintf(HEIGHT, " height=\"%.2f\"", h); + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper((int) h, 10, "setHeight") : ERROR; + char tmp[20]; + sprintf(tmp, " height=\"%.2f\"", h); + copyToMem(&HEIGHT, tmp); } void PhyphoxBleExperiment::Separator::setColor(const char *c) { - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkHex(c, "setColor") : ERROR; - memset(&COLOR[0], 0, sizeof(COLOR)); - strcat(COLOR, " color=\""); - strcat(COLOR, c); - strcat(COLOR, "\""); + ERROR = ERROR.MESSAGE == NULL ? err_checkHex(c, "setColor") : ERROR; + copyToMem(&COLOR, (std::string(c)).c_str()); } void PhyphoxBleExperiment::Separator::setXMLAttribute(const char * xml) { - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(xml, 98, "setXMLAttribute") : ERROR; - memset(&XMLAttribute[0], 0, sizeof(XMLAttribute)); - strcat(XMLAttribute, " "); - strcat(XMLAttribute, xml); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(xml, 98, "setXMLAttribute") : ERROR; + copyToMem(&XMLAttribute, (" " + std::string(xml)).c_str()); } void PhyphoxBleExperiment::Separator::getBytes(char *buffArray) { - strcat(buffArray,"\t\t\n"); strcat(buffArray, "\t\t\n"); - } diff --git a/src/subgraph.cpp b/src/subgraph.cpp new file mode 100644 index 0000000..e9fca12 --- /dev/null +++ b/src/subgraph.cpp @@ -0,0 +1,63 @@ +#include "phyphoxBleExperiment.h" +#include "copyToMem.h" + +void PhyphoxBleExperiment::Graph::Subgraph::getBytes(char *buffArray) +{ + //strcat(buffArray, "\n"); + strcat(buffArray, "\n\t\t\t"); + if (!INPUTX) {strcat(buffArray,"CH0");} else {strcat(buffArray,INPUTX);} + strcat(buffArray, "\n\t\t\t"); + if (!INPUTY) {strcat(buffArray,"CH1");} else {strcat(buffArray,INPUTY);} + strcat(buffArray, ""); +} + +void PhyphoxBleExperiment::Graph::Subgraph::setColor(const char *c){ + ERROR = ERROR.MESSAGE == NULL ? err_checkHex(c, "setColor") : ERROR; + copyToMem(&COLOR, (std::string(c)).c_str()); +} + +void PhyphoxBleExperiment::Graph::Subgraph::setLinewidth(float w){ + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(w, 10, "setLinewidth") : ERROR; + char tmp[10]; + sprintf(tmp, "%.2f", w); + copyToMem(&WIDTH, tmp); +} +/** + * @param s STYLE_DOTS + */ +void PhyphoxBleExperiment::Graph::Subgraph::setStyle(const char *s){ + Error styleError = err_checkStyle(s, "setStyle"); + ERROR = ERROR.MESSAGE == NULL ? styleError : ERROR; + if(styleError.MESSAGE == NULL){ + copyToMem(&STYLE, ("" + std::string(s)).c_str()); + } +} + +void PhyphoxBleExperiment::Graph::Subgraph::setChannel(int x, int y) +{ + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(x, numberOfChannels, "setChannel") : ERROR; + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(y, numberOfChannels, "setChannel") : ERROR; + + char tmpX[20]; + sprintf(tmpX, "CH%i", x); + copyToMem(&INPUTX, tmpX); + char tmpY[20]; + sprintf(tmpY, "CH%i", y); + copyToMem(&INPUTY, tmpY); +} \ No newline at end of file diff --git a/src/value.cpp b/src/value.cpp index 647b78c..fb4af63 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -1,56 +1,70 @@ #include "phyphoxBleExperiment.h" +#include "copyToMem.h" void PhyphoxBleExperiment::Value::setColor(const char *c) { - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkHex(c, "setColor") : ERROR; - memset(&COLOR[0], 0, sizeof(COLOR)); - strcat(COLOR, " color=\""); - strcat(COLOR, c); - strcat(COLOR, "\""); + ERROR = ERROR.MESSAGE == NULL ? err_checkHex(c, "setColor") : ERROR; + copyToMem(&COLOR, (std::string(c)).c_str()); } void PhyphoxBleExperiment::Value::setPrecision(int p) { - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkUpper(p, 999, "setPrecision") : ERROR; - sprintf(PRECISION, " precision=\"%d\"", p); + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(p, 999, "setPrecision") : ERROR; + char tmp[20]; + sprintf(tmp,"%i", p); + copyToMem(&PRECISION, tmp); } void PhyphoxBleExperiment::Value::setUnit(const char* u) { - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(u, 12, "setUnit") : ERROR; - memset(&UNIT[0], 0, sizeof(UNIT)); - strcat(UNIT, " unit=\""); - strcat(UNIT, u); - strcat(UNIT, "\""); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(u, 12, "setUnit") : ERROR; + copyToMem(&UNIT, (std::string(u)).c_str()); } void PhyphoxBleExperiment::Value::setChannel(int c) { - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkUpper(c, numberOfChannels, "setChannel") : ERROR; - sprintf(INPUTVALUE, "CH%i", c); + ERROR = ERROR.MESSAGE == NULL ? err_checkUpper(c, numberOfChannels, "setChannel") : ERROR; + char tmp[20]; + sprintf(tmp, "CH%i", c); + copyToMem(&INPUTVALUE, tmp); } void PhyphoxBleExperiment::Value::setXMLAttribute(const char *xml){ - ERROR = (strcmp(ERROR.MESSAGE, "")==0) ? err_checkLength(xml, 98, "setXMLAttribute") : ERROR; - memset(&XMLAttribute[0], 0, sizeof(XMLAttribute)); - strcat(XMLAttribute, " "); - strcat(XMLAttribute, xml); + ERROR = ERROR.MESSAGE == NULL ? err_checkLength(xml, 98, "setXMLAttribute") : ERROR; + copyToMem(&XMLAttribute, (" " + std::string(xml)).c_str()); } void PhyphoxBleExperiment::Value::getBytes(char *buffArray) { strcat(buffArray,"\t\t\n"); strcat(buffArray, "\t\t\t"); - strcat(buffArray, INPUTVALUE); - strcat(buffArray, "\n\t\t\n"); - + if (!INPUTVALUE) {strcat(buffArray,"CH3");} else {strcat(buffArray,INPUTVALUE);} + strcat(buffArray, "\n\t\t\n"); } diff --git a/src/view.cpp b/src/view.cpp index 1a2ca0b..13792c4 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -1,5 +1,5 @@ #include "phyphoxBleExperiment.h" - +#include "copyToMem.h" void PhyphoxBleExperiment::View::addElement(Element& e) { @@ -9,33 +9,27 @@ void PhyphoxBleExperiment::View::addElement(Element& e) break; } } - } void PhyphoxBleExperiment::View::setLabel(const char *l){ - memset(&LABEL[0], 0, sizeof(LABEL)); - strcat(LABEL, " label=\""); - strcat(LABEL, l); - strcat(LABEL, "\""); + copyToMem(&LABEL, (" label=\"" + std::string(l) + "\"").c_str()); } void PhyphoxBleExperiment::View::setXMLAttribute(const char *xml){ - memset(&XMLAttribute[0], 0, sizeof(XMLAttribute)); - strcat(XMLAttribute, " "); - strcat(XMLAttribute, xml); + copyToMem(&XMLAttribute, (" " + std::string(xml)).c_str()); } void PhyphoxBleExperiment::View::getBytes(char *buffArray, uint8_t elem) { if(elem == 0) { strcat(buffArray, "\t\n"); } if(ELEMENTS[elem]!=nullptr){ - if(strcmp(ELEMENTS[elem]->ERROR.MESSAGE, "") == 0) { + if(ELEMENTS[elem]->ERROR.MESSAGE == NULL) { ELEMENTS[elem]->getBytes(buffArray); } }