Zelfbouw Arduino Nano Oscilloscoop (10 Hz – 50 kHz) met 128×64 LCD
Onderdelen en benodigdheden
| Onderdeel | Aantal |
|---|---|
| Arduino Nano R3 | 1 |
| Condensator 100 µF | 1 |
| ST7920 LCD 128×64 pixels | 1 |
| Draaipotentiometer (algemeen) | 2 |
| Drukknop (momentaan) | 3 |
Benodigde tools
- Solderbout
Apps en online diensten
- Arduino IDE
Over dit project
Dit project beschrijft een eenvoudige oscilloscoop met een bereik van 10 Hz tot 50 kHz. Dat is een zeer groot bereik voor een apparaat dat geen externe ADC-chip gebruikt, maar uitsluitend de Arduino.
Het resultaat wordt weergegeven op een relatief groot LCD-scherm (ST7920) met een resolutie van 128×64 pixels. Het meetgebied is 96×64 pixels; de rechter 32×64 pixels tonen frequentie, Vpp en overige parameters.
De opbouw is extreem simpel en bestaat uit weinig componenten:
- Arduino Nano
- ST7920 LCD-display 128×64
- Drie momentane drukknoppen
- Twee potentiometers
- Één condensator van 100 µF
Functionaliteiten:
- Auto-trigger (zeer stabiele weergave)
- Tijdbasis: 0,02 ms/div tot 10 ms/div (1-2-5 stappen, 9 niveaus)
- Hold-functie: bevriest golfvorm en parameters
De verticale positie wordt ingesteld met de 50 kΩ potentiometer, de contrast met de 10 kΩ potentiometer. Getest met sinus- en blokgolfgenerator.
Hoewel het geen professioneel instrument is, is het uitstekend geschikt voor educatieve doeleinden of in de lab voor lage-frequente signalen, gegeven de lage kosten en eenvoudige bouw.
Code
De code gebruikt de U8glib-bibliotheek voor het ST7920-display. Hieronder de volledige sketch.
#include <U8glib.h>
U8GLIB_ST7920_128X64_4X u8g(6, 5, 4); // E, RW, RS
int Input = A0;
int Key_add = 8;
int Key_sub = 9;
int Key_hold = 10;
int x, y;
int i, i1, i2, V_min, V_max, V_mid, t, t0, t1, sta, Key = 1, hold = 0;
long Freq;
float Vpp;
int Y[96];
int Buffer[192];
// Bitmap voor opstartscherm (verkort)
const uint8_t L[] PROGMEM = { /* ... grote bitmap-array ... */ };
void setup() {
pinMode(Key_add, INPUT_PULLUP);
pinMode(Key_sub, INPUT_PULLUP);
pinMode(Key_hold, INPUT_PULLUP);
// ADC configuratie voor snelle sampling
ADMUX = 0x60; // AVCC referentie, ADC0
ADCSRA = 0xE2; // ADEN, ADSC, ADATE, ADPS=2 (prescaler 4 -> 2 MHz ADC clock)
u8g.setFont(u8g_font_5x7);
u8g.firstPage();
do {
u8g.drawBitmapP(0, 0, 16, 64, L);
} while (u8g.nextPage());
delay(2000);
}
void loop() {
sample();
Measure();
Transform();
Key_scan();
if (hold == 0) {
u8g.firstPage();
do {
draw();
} while (u8g.nextPage());
}
}
void sample() {
for (i = 0; i < 192; i++) {
Buffer[i] = ADCH; // Lees hoogste 8 bits van ADC
switch (Key) {
case 1: break;
case 2: delayMicroseconds(4); break;
case 3: delayMicroseconds(10); break;
case 4: delayMicroseconds(23); break;
case 5: delayMicroseconds(60); break;
case 6: delayMicroseconds(123); break;
case 7: delayMicroseconds(248); break;
case 8: delayMicroseconds(623); break;
case 9: delayMicroseconds(1247); break;
default: break;
}
}
}
void Measure() {
V_max = Buffer[0];
V_min = Buffer[0];
for (i = 0; i < 192; i++) {
if (Buffer[i] > V_max) V_max = Buffer[i];
if (Buffer[i] < V_min) V_min = Buffer[i];
}
V_mid = (V_max + V_min) / 2;
Vpp = (V_max - V_min) * 5.0 / 255.0;
// Nul-doorgang detectie voor frequentie
for (i = 0; i < 97; i++) {
if (Buffer[i] < V_mid && Buffer[i+1] >= V_mid) { i1 = i; break; }
}
for (i = i1 + 1; i < 98 + i1; i++) {
if (Buffer[i] < V_mid && Buffer[i+1] >= V_mid) { i2 = i; break; }
}
t = i2 - i1;
if (t > 0) Freq = 8000L / t; else Freq = 0; // 8000 samples/sec basis
}
void Transform() {
for (sta = 0; sta < 96; sta++) {
if (Buffer[sta] < 128 && Buffer[sta+2] > 128) break;
}
for (i = 0; i < 96; i++) Y[i] = 63 - (Buffer[i+sta] >> 2);
}
void draw() {
// Teken golfvorm
for (x = 0; x < 95; x++) u8g.drawLine(x, Y[x], x, Y[x+1]);
u8g.drawFrame(0, 0, 97, 64);
u8g.drawLine(48, 0, 48, 63); // Middelijn verticaal
u8g.drawLine(0, 32, 96, 32); // Middelijn horizontaal
// Rasterlijnen
for (x = 0; x < 96; x += 8) u8g.drawLine(x, 31, x, 33);
for (y = 0; y < 64; y += 8) u8g.drawLine(47, y, 49, y);
for (x = 8; x < 96; x += 8)
for (y = 8; y < 64; y += 8)
u8g.drawPixel(x, y);
// Info rechterzijde
u8g.drawStr(98, 7, "MS/div");
u8g.drawStr(98, 23, "V/div");
u8g.drawStr(98, 30, "0.324");
u8g.drawStr(98, 40, "Vpp");
u8g.setPrintPos(98, 47);
u8g.print(Vpp);
u8g.drawStr(118, 47, "V");
u8g.drawStr(98, 55, "F(HZ)");
// Tijdbasis en frequentie per Key-niveau
switch (Key) {
case 1: u8g.drawStr(98, 14, "0.02"); u8g.setPrintPos(98, 62); u8g.print(Freq * 50); break;
case 2: u8g.drawStr(98, 14, "0.05"); u8g.setPrintPos(98, 62); u8g.print(Freq * 20); break;
case 3: u8g.drawStr(98, 14, " 0.1"); u8g.setPrintPos(98, 62); u8g.print(Freq * 10); break;
case 4: u8g.drawStr(98, 14, " 0.2"); u8g.setPrintPos(98, 62); u8g.print(Freq * 5); break;
case 5: u8g.drawStr(98, 14, " 0.5"); u8g.setPrintPos(98, 62); u8g.print(Freq * 2); break;
case 6: u8g.drawStr(98, 14, " 1"); u8g.setPrintPos(98, 62); u8g.print(Freq); break;
case 7: u8g.drawStr(98, 14, " 2"); u8g.setPrintPos(98, 62); u8g.print(Freq / 2); break;
case 8: u8g.drawStr(98, 14, " 5"); u8g.setPrintPos(98, 62); u8g.print(Freq / 5); break;
case 9: u8g.drawStr(98, 14, " 10"); u8g.setPrintPos(98, 62); u8g.print(Freq / 10); break;
default: break;
}
}
void Key_scan() {
if (digitalRead(Key_add) == LOW) {
while (digitalRead(Key_add) == LOW);
Key++; if (Key == 10) Key = 9; delay(10);
}
if (digitalRead(Key_sub) == LOW) {
while (digitalRead(Key_sub) == LOW);
Key--; if (Key == 0) Key = 1; delay(10);
}
if (digitalRead(Key_hold) == LOW) {
while (digitalRead(Key_hold) == LOW);
hold = ~hold; delay(10);
}
}
Schema
Productieproces
- Bouw Je Eigen LUMAZOID: Een DIY Arduino Muziek Visualizer
- Bouw een 20 kHz Arduino Oscilloscoop op een Nokia 5110 LCD – Eenvoudige DIY Handleiding
- Een Arduino Iron Man bouwen: onderdelen, sensoren en stapsgewijze handleiding
- Find Me: Slimme Item Locator met Arduino en Bluetooth
- Interactieve LED-matrix deurdisplay met PIR-bewegingsensor – Arduino vakantiegroet
- DIY Arduino Luchtbevochtiger Controller met Relais – Veilige Hoogspanningsopstelling
- Bouw een DIY Voltmeter met Arduino en Nokia 5110 Display – Stap-voor-Stap Handleiding
- Realtime afstandsmeting met Arduino Sonar & Processing visualisatie
- MobBob: Bouw Je Eigen Arduino Robot, Naadloos Bestuurd via Android Smartphone
- Zelfbouw Arduino Nano Oscilloscoop (10 Hz – 50 kHz) met 128×64 LCD
- Bouw een Aangepaste Arduino Joystick Stuurwiel voor Gaming