Arduino示波器(一)一、背景 自ADS1115被Arduino/ESP32/phyphox藍牙實驗開發(fā)組發(fā)掘,小伙伴們突然有了一個企圖:開發(fā)一個極為便宜的示波器——真正的金錢上的投入少,因為phyphox實驗主打可移動性和低成本——于是查閱了一些中外文獻(當然是業(yè)余的擠出來的時間),發(fā)現大致思路有這么兩種:一種是主張精確和準確,紛紛提出STM32、ADC采樣等。我是不主張的,追求精確和準確干嘛不用專業(yè)的示波器?如果不是玩物喪志的沉溺于diy真的沒有必要;另一種則是使用12864等顯示波形,但是我們是在研究Arduino&phyphox示波器,最直接的顯示途徑,便是phyphox了。這樣算下來,大致的可取路徑有以下幾個方向: 使用Arduino/ESP32采集數據,然后使用phyphox來充當顯示屏。這個方案實在太過簡單,略過了,不研究。 使用Arduino/ESP32采集數據,使用Arduino IDE自帶的串口繪圖器充當顯示屏。這個方案當然極為方便,但是要在串口繪圖器上調整div或者hold,以及顯示數字,好象不太可能??梢源致允褂茫匀宦赃^,不研究。 使用Arduino/ESP32采集數據,用其他應用程序來顯示波形。這個方案,最優(yōu)搭配絕對是processing莫屬!于是到processing官網去查找示波器代碼,果然有!簡單改改,放在這里用了,是為(一). 這最后的方案,便是12864。自接觸單片機以來,只研究過1206和OLED,還沒有用過12864,這一個嘗試,便只記錄Arduino+Processing。
二、Arduino代碼 什么新意也沒有,從A0讀電壓,然后送給串口。注意只測了正電壓。 #define ANALOG_IN 0
void setup() { Serial.begin(9600); //Serial.begin(115200); }
void loop() { int val = analogRead(ANALOG_IN); Serial.write( 0xff ); Serial.write( (val >> 8) & 0xff ); Serial.write( val & 0xff ); }
三、processing代碼 以下代碼,在processing 3.54下調試通過。代碼不是我寫的。這個代碼似乎很不processing,但人家是現成的代碼。不必改了。 按鍵盤上的+號,圖象實現Y增益,-號Y增益減小,按p鍵,圖象保持,即hold。 import processing.serial.*;
Serial port; // Create object from Serial class int val; // Data received from the serial port int[] values; float zoom; boolean paused;
void setup() { size(1280, 600); // Open the port that the board is connected to and use the same speed (9600 bps) port = new Serial(this, "COM9", 9600);//這里直接改串口號,運行速度極快 values = new int[width]; zoom = 1.0f; paused = false; smooth(); }
int getY(int val) { return (int)(height - val / 1023.0f * (height - 1)); }
int getValue() { int value = -1; while (port.available() >= 3) { if (port.read() == 0xff) { value = (port.read() << 8) | (port.read()); } } return value; }
void pushValue(int value) { for (int i=0; i<width-1; i++) values[i] = values[i+1]; values[width-1] = value; }
void drawLines() { stroke(255); int displayWidth = (int) (width / zoom); int k = values.length - displayWidth; int x0 = 0; int y0 = getY(values[k]); for (int i=1; i<displayWidth; i++) { k++; int x1 = (int) (i * (width-1) / (displayWidth-1)); int y1 = getY(values[k]); line(x0, y0, x1, y1); x0 = x1; y0 = y1; } }
void drawGrid() { stroke(255, 0, 0); line(0, height/2, width, height/2); }
void keyReleased() { switch (key) { case '+': zoom *= 2.0f; println(zoom); if ( (int) (width / zoom) <= 1 ) zoom /= 2.0f; break; case '-': zoom /= 2.0f; if (zoom < 1.0f) zoom *= 2.0f; break; case 'p': paused = !paused; break; } }
void draw() { if(paused) {return;} background(0); drawGrid(); val = getValue(); if (val != -1) { pushValue(val); } drawLines(); }

|