Arduino Oszilloscope bauen

Hallo Zusammen

Ich möchte mir folgendes Oszi bauen: Arduino Oscilloscope

Kann ich dieses Oszi mit einem Uno realisieren wohl eher nicht hier nochmals der Sketch:

/*
 * Arduino Oscilloscope using a graphic LCD
 * The max sampling rates are 4.3ksps with 2 channels and 8.6ksps with a channel.
 * Copyright (c) 2009, Noriaki Mitsunaga
 */

#include <ks0108.h>
#include <Arial14.h>  // font definitions 

#define txtLINE0   0
#define txtLINE1   16
#define txtLINE2   30
#define txtLINE3   46

const int LCD_WIDTH = 128;
const int LCD_HEIGHT = 64;
const int SAMPLES = 100;
const int ad_sw = 3;                    // Analog 3 pin for switches
const int ad_ch0 = 4;                   // Analog 4 pin for channel 0
const int ad_ch1 = 5;                   // Analog 5 pin for channel 1
const unsigned long VREF[] = {49, 98, 244, 488, 976}; // reference voltage 5.0V ->  50 :   1V/div range (100mV/dot)
                                        //                        -> 100 : 0.5V/div
                                        //                        -> 250 : 0.2V/div
                                        //                        -> 500 : 100mV/div
                                        //                       -> 1000 :  50mV/div
const int MILLIVOL_per_dot[] = {100, 50, 20, 10, 5}; // mV/dot
const int MODE_ON = 0;
const int MODE_INV = 1;
const int MODE_OFF = 2;
const char *Modes[] = {"ON", "INV", "OFF"};
const int TRIG_AUTO = 0;
const int TRIG_NORM = 1;
const int TRIG_SCAN = 2;
const int TRIG_ONE  = 3;
const char *TRIG_Modes[] = {"Auto", "Norm", "Scan", "One"};
const int TRIG_E_UP = 0;
const int TRIG_E_DN = 1;
#define RATE_MIN 0
#define RATE_MAX 13
const char *Rates[] = {"F1-1", "F1-2 ", "F2  ", "5ms", "10ms", "20ms", "50ms", "0.1s", "0.2s", "0.5s", "1s", "2s", "5s", "10s"};
#define RANGE_MIN 0
#define RANGE_MAX 4
const char *Ranges[] = {" 1V ", "0.5V", "0.2V", "0.1V", "50mV"};
byte range0 = RANGE_MIN;
byte range1 = RANGE_MIN;
byte ch0_mode = 0, ch1_mode = 0, rate = 5;
byte trig_mode = TRIG_AUTO, trig_lv = 30, trig_edge = TRIG_E_UP, trig_ch = 0;
byte Start = 1, menu = 0;
short ch0_off = 0, ch1_off = 0;
unsigned long startMillis;
byte data[4][SAMPLES];                   // keep twice of the number of channels to make it a double buffer
byte sample=0;                           // index for double buffer

void setup(){
  GLCD.Init(NON_INVERTED);   // initialise the library, non inverted writes pixels onto a clear screen
  GLCD.SelectFont(Arial_14); // you can also make your own fonts, see playground for details  
 
  Serial.begin(9600);
  GLCD.ClearScreen();
  DrawGrid();
  DrawText();
}

void CheckSW() {
  static unsigned short oain[2];
  static unsigned long Millis = 0, oMillis = 0;
  unsigned long ms;
  unsigned short ain = analogRead(ad_sw);
  
  ms = millis();
  if ((ms - Millis)<5)
    return;
  Millis = ms;
  
  if (!(abs(oain[0] - oain[1])>10 && abs(oain[1] - ain)<2)) {
    oain[0] = oain[1];
    oain[1] = ain;
    return;
  }
  oain[0] = oain[1];
  oain[1] = ain;
  
  if (ain > 950 || (Millis - oMillis)<200)
    return;
  oMillis = Millis;

  // Serial.println(ain);
  
  int sw;
  for (sw = 0; sw < 10; sw ++) {
    const int sw_lv[] = {889, 800, 700, 611, 514, 419, 338, 231, 132, 70};
    if (ain > sw_lv[sw])
      break;
  }
  // Serial.println(sw);
  
  switch (menu) {
  case 0:
  default:
    menu0_sw(sw); 
    break;
  case 1:
    menu1_sw(sw); 
    break;
  case 2:
    menu2_sw(sw); 
    break;
  }
  
  DrawText();
}

void menu0_sw(int sw) {  
  switch (sw) {
   case 0:
    // START/HOLD
    if (Start)
       Start = 0;
     else
       Start = 1;
    break;
   case 1:
    // CH0 RANGE -
    if (range0 < RANGE_MAX)
      range0 ++;
    break;
   case 2:
    // CH1 RANGE -
    if (range1 < RANGE_MAX)
      range1 ++;
    break;
   case 3:
    // RATE FAST
    if (rate > 0)
      rate --;
    break;
   case 4:
    // TRIG MODE
    if (trig_mode < TRIG_ONE)
      trig_mode ++;
    else
      trig_mode = 0;
    break;
   case 5:
    // SEND
    SendData();
    break;
   case 6:
    // TRIG MODE
    if (trig_mode > 0)
      trig_mode --;
    else
      trig_mode = TRIG_ONE;
    break;
   case 7:
    // RATE SLOW
    if (rate < RATE_MAX)
      rate ++;
    break;
   case 8:
    // CH1 RANGE +
    if (range1 > 0)
      range1 --;
    break;
   case 9:
    // CH0 RANGE +
    if (range0 > 0)
      range0 --;
    break;
   case 10:
   default:
    // MENU SW
    menu ++;
     break;
  }
}

void menu1_sw(int sw) {  
  switch (sw) {
   case 0:
    // START/HOLD
    if (Start)
       Start = 0;
     else
       Start = 1;
    break;
   case 1:
    // CH0 offset +
    if (ch0_off < 1023)
      ch0_off += 1024/VREF[range0];
    break;
   case 2:
    // CH1 offset +
    if (ch1_off < 1023)
      ch1_off += 1024/VREF[range1];
    break;
   case 3:
    // trigger level +
    if (trig_lv < 60)
      trig_lv ++;
    break;
   case 4:
   case 6:
    // TRIG EDGE
    if (trig_edge == TRIG_E_UP)
      trig_edge = TRIG_E_DN;
    else
      trig_edge = TRIG_E_UP;
    break;
   case 5:
    // SEND
    SendData();
    break;
   case 7:
    // trigger level -
    if (trig_lv > 0)
      trig_lv --;
    break;
   case 8:
    // CH1 OFF -
    if (ch1_off > -1023)
      ch1_off -= 1024/VREF[range1];
    break;
   case 9:
    // CH0 OFF -
    if (ch0_off > -1023)
      ch0_off -= 1024/VREF[range0];
    break;
   case 10:
   default:
    // MENU SW
    menu ++;
     break;
  }
}

void menu2_sw(int sw) {  
  switch (sw) {
   case 0:
    // START/HOLD
    if (Start)
       Start = 0;
     else
       Start = 1;
    break;
   case 1:
    if (ch0_mode < 2)
      ch0_mode ++;
    break;
   case 2:
    if (ch1_mode < 2)
      ch1_mode ++;
    break;
   case 3:
   case 7:
    // TRIG channel
    if (trig_ch == 0)
      trig_ch = 1;
    else
      trig_ch = 0;
    break;
   case 5:
    // SEND
    SendData();
    break;
   case 8:
    if (ch1_mode > 0)
      ch1_mode --;
    break;
   case 9:
    if (ch0_mode > 0)
      ch0_mode --;
    break;
   case 10:
    // MENU SW
    menu = 0;
     break;
   case 4:
   case 6:
   default:
    // none
    break;
  }
}

void SendData() {
  Serial.print(Rates[rate]);
  Serial.println("/div (10 samples)");
  for (int i=0; i<SAMPLES; i ++) {
      Serial.print(data[sample + 0][i]*MILLIVOL_per_dot[range0]);
      Serial.print(" ");
      Serial.println(data[sample + 1][i]*MILLIVOL_per_dot[range1]);
   } 
}

void DrawGrid() {
    for (int x=0; x<=SAMPLES; x += 2) { // Horizontal Line
      for (int y=0; y<=60; y += 10) {
        GLCD.SetDot(x, y, BLACK);
        CheckSW();
      }
    }
    for (int x=0; x<=SAMPLES; x += 10 ) { // Vertical Line
      for (int y=0; y<=60; y += 2) {
        GLCD.SetDot(x, y, BLACK);
        CheckSW();
      }
    }
}

void DrawText() {
    GLCD.FillRect(101,txtLINE0,28,64, WHITE);  // clear text area that will be drawn below

Leider musste ich den Sketch einkürzen ( die Zeilen am Schluss) da sonst die zulässige Zeichenlänge überschritten wird.

Eventuell kann jemand ja was aus den Code oder dem Plan rauslesen.

Wieso soll das mit einem Arduino UNO nicht gehen?
Grüße Uwe

Hi Uwe

danke für die schnelle Antwort.
Ich dachte nur dass der Sketch für nen UNO zu groß währe.
Ich lese aus deiner Antwort dass es geht dann werde ich das mal probieren.

Grüße Rudi

Rudi01:
Ich dachte nur dass der Sketch für nen UNO zu groß währe.
Ich lese aus deiner Antwort dass es geht dann werde ich das mal probieren.

Der Sketch wohl nicht unbedingt, aber der RAM-Speicherverbrauch dürfte zu hoch sein.

Ein UNO hat nur 2KB RAM, und da ist von Font-Handling bis Ansteuerung eines grafischen Displays alles mögliche im Sketch drin, was ordentlich RAM verbraucht.

Ich schätze mal, das läuft eher nicht, wenn es nicht angegeben ist, dass es auch auf einem UNO läuft.

hi,

verwende doch einen 1284P um 5€, dann hast Du speicher genug und verbrätst nicht Deinen UNO.

gruß stefan.

jurs wenn der UNO zuwenig RAM hat, dann haben es auch die älteren Arduino Versionen. Bräuchte es einen Arduino MEGA, dann wäre es auch geschrieben.

Wahrscheinlich ist der Sketch an den UNO sprich IDE1.0.x anzugleichen

Grüße Uwe

Hi zusammen

also übertragen lässt er sich nur hab ich noch keine Anzeige muss mal die Verdrahtung überprüfen.
Da gibts auch noch zwei Ungereimtheiten zwischen Plan und meinem Display.
Aber jetzt ist Feierabend denn morgen gehts wieder zur Arbeit

Du weißt aber, daß das Oszilloscop kaum zu gebrauchen ist. Bei einer Sampelrate von 4.3ksps bzw 8.6ksps kannst Du Kurven weit darunter darstellen. Bereits ein Arduino-PWM-Signal ist nicht sinnvoll darzustellen. Du siehst zwar die Rechteckspannung kannst aber die verschiedenen Werte nicht außeinanderhalten.

Bevor Du Geld für den Arduino und das Display ausgibst kauf Dir besser ein http://www.watterott.com/de/Digitales-Speicher-Oszilloskop-Bausatz-DSO-062?x75259=7870302371897e4c6bdad1c531d0e81a
oder http://www.watterott.com/de/Digitales-Speicher-Oszilloskop-Bausatz-DSO-096011?x75259=7870302371897e4c6bdad1c531d0e81a

Aber billige analoge Oszilloscope sind besser als billige digitale.

Grüße Uwe

Ich denke du bist mit dem DSO Nano v3.
http://www.seeedstudio.com/depot/dso-nano-v3-p-1358.html?cPath=174
oder dem DSO Quad

Wir nutzten das Quad bei uns auf der Arbeit und für die Meisten Messungen absolut ausreichen (nur bedingt für einen Anfänger geeignet da es keine Automatik gibt für Range und s/div). Man kann es auch nicht mir einem Fluke 123 vergleichen.

oder das Dingen von Velleman

Gruß
Der Dani