/************************************************************************ M5StackFire simple oscilloscope example The oscilloscope has a auto trigger function to achive a stable visual impression when a repeating signal like a sine wave is applied. original version STM32F429 Discovery June 2018, ChrisMicro this version reworked for M5StackFire September 2018, ChrisMicro ************************************************************************/ #include #define M5STACKFIRE_MICROPHONE_PIN 34 #define M5STACKFIRE_SPEAKER_PIN 25 // speaker DAC, only 8 Bit #define HORIZONTAL_RESOLUTION 320 #define VERTICAL_RESOLUTION 240 #define POSITION_OFFSET_Y 20 #define SIGNAL_LENGTH HORIZONTAL_RESOLUTION uint16_t oldSignal[SIGNAL_LENGTH]; uint16_t adcBuffer[SIGNAL_LENGTH]; #define SAMPLING_TIME_US 25 #define ANALOG_SIGNAL_INPUT M5STACKFIRE_MICROPHONE_PIN void setup() { dacWrite(M5STACKFIRE_SPEAKER_PIN, 0); // make sure that the speaker is quite M5.Lcd.begin(); M5.Power.begin(); M5.Lcd.fillScreen(BLACK); M5.Lcd.fillRect(10, 1, 150, 160, BLACK); M5.Lcd.setCursor(0, 0); M5.Lcd.setTextColor(GREEN); // M5.Lcd.setTextSize(3); M5.Lcd.setTextSize(1); M5.Lcd.println("analog input MIC"); M5.Lcd.print("sampling frequency: "); M5.Lcd.print(1000000 / SAMPLING_TIME_US); M5.Lcd.println(" Hz"); } void waitForAutoTrigger() { uint32_t triggerLevel = 512; uint32_t hysteresis = 10; uint32_t timeOut_ms = 100; uint32_t timeOutLimit = millis() + timeOut_ms; uint32_t timeOutFlag = false; uint32_t adcValue = 0; adcValue = analogRead(ANALOG_SIGNAL_INPUT); // wait for low level while ((adcValue > triggerLevel - hysteresis) && !timeOutFlag) { adcValue = analogRead(ANALOG_SIGNAL_INPUT); if (millis() > timeOutLimit) timeOutFlag = 1; } if (!timeOutFlag) { // wait for high level while ((adcValue < triggerLevel + hysteresis) && (millis() < timeOutLimit)) { adcValue = analogRead(ANALOG_SIGNAL_INPUT); } } } void showSignal() { int n; int oldx; int oldy; int oldSig; int x, y; for (n = 0; n < SIGNAL_LENGTH; n++) { x = n; y = map(adcBuffer[n], 0, 4096, VERTICAL_RESOLUTION, POSITION_OFFSET_Y); if (n > 0) { // delete old line element M5.Lcd.drawLine(oldx, oldSig, x, oldSignal[n], BLACK); // draw new line element if (n < SIGNAL_LENGTH - 1) // don't draw last element because it // would generate artifacts { M5.Lcd.drawLine(oldx, oldy, x, y, GREEN); } } oldx = x; oldy = y; oldSig = oldSignal[n]; oldSignal[n] = y; } } void loop(void) { int n; uint32_t nextTime = 0; waitForAutoTrigger(); // record signal for (n = 0; n < SIGNAL_LENGTH; n++) { adcBuffer[n] = analogRead(ANALOG_SIGNAL_INPUT); // wait for next sample while (micros() < nextTime) ; nextTime = micros() + SAMPLING_TIME_US; } showSignal(); }