/* First version of nano timer 30/12/2020 nano_sound.ino and https://github.com/Staacks/phyphox-arduino#randomnumbersino are used Second version - b : send only time difference 3d version - c : PDM.end() and print format 2/01/2021 RGB led - e: 5/09/2021 */ #include #include #include // #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) // #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) // Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); #include #include // buffer to read samples into, each sample is 16-bits short sampleBuffer[256]; // number of samples read volatile int samplesRead; unsigned long runs; short ntime; float mtime[6]; float msound[6]; float art; // Arduino threshold float tDelay; float intervalMax = 0; short nMax = 0; float t = 0.0; float t1; float dt; char board_name[] = "Arduino"; const int ledRED = 22; const int ledGREEN = 23; const int ledBLUE = 24; void setup() { Serial.begin(9600); while(!Serial); pinMode(ledRED, OUTPUT); pinMode(ledGREEN, OUTPUT); pinMode(ledBLUE, OUTPUT); digitalWrite(ledRED, HIGH); // dark digitalWrite(ledGREEN, HIGH); digitalWrite(ledBLUE, HIGH); /* Minimum interval between two connection events allowed for a connection. It shall be less than or equal to maxConnectionInterval. This value, in units of 1.25ms, is included in the range [0x0006 : 0x0C80]. */ PhyphoxBLE::minConInterval = 24; //6 = 7.5ms /* Maximum interval between two connection events allowed for a connection. It shall be greater than or equal to minConnectionInterval. This value is in unit of 1.25ms and is in the range [0x0006 : 0x0C80]. */ PhyphoxBLE::maxConInterval = 24; //6 = 7.5ms /* Number of connection events the slave can drop if it has nothing to communicate to the master. This value shall be in the range [0x0000 : 0x01F3]. */ PhyphoxBLE::slaveLatency = 0; // /* Link supervision timeout for the connection. Time after which the connection is considered lost if the device didn't receive a packet from its peer. This value is in the range [0x000A : 0x0C80] and is in unit of 10 ms. */ PhyphoxBLE::timeout = 50; //10 = 100ms PhyphoxBLE::start(board_name); //Start the BLE server // the name of the board can be changed at the beginning of the program // PhyphoxBLE::configHandler = &receivedData; // receivedData(); art = 400.0; tDelay = 0.5; // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); runs = 0L; ntime = 0; mtime[0] = 0; msound[0] = 0; dt = 1.0 / 16000; // configure the data receive callback PDM.onReceive(onPDMdata); // initialize PDM with: // - one channel (mono mode) // - a 16 kHz sample rate if (!PDM.begin(1, 16000)) { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH voltage level) while (1); } display.begin(SSD1306_SWITCHCAPVCC); display.display(); delay(2000); display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); digitalWrite(ledRED, HIGH); // green led digitalWrite(ledGREEN, LOW); digitalWrite(ledBLUE, HIGH); } // end setup void loop() { // PhyphoxBLE::poll(); // ? // Only required for the Arduino Nano 33 IoT, // but it does no harm for other boards. // wait for samples to be read if (samplesRead) { // looking for the maximum intervalMax = 0; nMax = 0; for (int n = 0; n < samplesRead; n++) { if (sampleBuffer[n] > intervalMax) { intervalMax = sampleBuffer[n]; nMax = n; } // end if 2 } // end for (looking for the maximum) t1 = t + nMax * dt; if ((intervalMax > art) && ((t1-mtime[ntime]) > tDelay)) { ++ntime; mtime[ntime] = t1; msound[ntime] = intervalMax; } t += samplesRead * dt; samplesRead = 0; // clear the read count } // end if (samplesRead) ++runs; if (ntime == 2) { float deltaTime = mtime[2] - mtime[1]; display.clearDisplay(); display.setCursor(0,0); display.print(art, 0); display.print(";"); display.println(tDelay, 1); display.print(deltaTime, 4); display.display(); PhyphoxBLE::write(deltaTime); delay(50); digitalWrite(ledRED, LOW); // red digitalWrite(ledGREEN, HIGH); digitalWrite(ledBLUE, HIGH); // remains here for about 3 sec and blinking for (int i = 0; i < 3; i++) { blinking(ntime, 100, 100); delay(1000); // wait for 1 second } // end for digitalWrite(LED_BUILTIN, HIGH); // led on, waiting for 2 claps ++ntime; } else if (ntime == 1) { digitalWrite(ledRED, HIGH); // blue digitalWrite(ledGREEN, HIGH); digitalWrite(ledBLUE, LOW); } else if (ntime == 3) { digitalWrite(ledRED, HIGH); // dark digitalWrite(ledGREEN, HIGH); digitalWrite(ledBLUE, HIGH); } // end if ntime // after 2 more claps returns to original state and restart if (ntime>=5) { t = 0; runs = 0L; ntime = 0; receivedData(); digitalWrite(LED_BUILTIN, LOW); // led off, ready for restart digitalWrite(ledRED, HIGH); // green digitalWrite(ledGREEN, LOW); digitalWrite(ledBLUE, HIGH); } } // end loop void receivedData() { uint8_t readArray[8] = {}; uint8_t one[4], two[4]; int i; i=0; while (readArray[4]==0 && readArray[5]==0 && readArray[6]==0 && readArray[7]==0) { PhyphoxBLE::read(&readArray[0], 8); // does not work with 2 floats delay(10); i++; if (i > 100) break; } Serial.println(i); Serial.println(sizeof(readArray)); memcpy(one, readArray, sizeof(one)); memcpy(two, &readArray[4], sizeof(two)); // 3 or 4 ?? for (i=0; i<8; i++) { Serial.print("/"); Serial.print(byte(readArray[i]), HEX); } Serial.println("/"); for (i=0; i<4; i++) { Serial.print("."); Serial.print(one[i], HEX); } Serial.print(" "); for (i=0; i<4; i++) { Serial.print(","); Serial.print(two[i], HEX); } Serial.println(); art = *(float*)&(one); // was working tDelay = *(float*)&(two); // art = (float)atof(one); // tDelay = (float)atof(two); Serial.println(art, 9); Serial.println(tDelay, 9); Serial.println("------------------"); if (art<10) art = 410; if (tDelay<0.1) tDelay = 0.3; blinking(4, 50, 200); } void onPDMdata() { // query the number of bytes available int bytesAvailable = PDM.available(); // read into the sample buffer PDM.read(sampleBuffer, bytesAvailable); // 16-bit, 2 bytes per sample samplesRead = bytesAvailable / 2; } void blinking(int blinks, int tON, int tOFF) { for (int i = 0; i < blinks; i++) { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) delay(tON); // wait for tON ms digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(tOFF); // wait for tOFF ms } }