Pages: [1]   Go Down
Author Topic: Arduino Oszilloscope bauen  (Read 1314 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 4
Posts: 127
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Zusammen

Ich möchte mir folgendes Oszi bauen: http://n.mtng.org/ele/arduino/oscillo.html

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

Code:
/*
 * 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.
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 249
Posts: 21189
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Full Member
***
Karma: 4
Posts: 127
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 134
Posts: 2854
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Wien
Offline Offline
Edison Member
*
Karma: 26
Posts: 1836
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi,

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

gruß stefan.
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 249
Posts: 21189
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
http://arduino.cc/forum/index.php/topic,127552.msg959328.html#msg959328

Grüße Uwe
Logged

Offline Offline
Full Member
***
Karma: 4
Posts: 127
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 249
Posts: 21189
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

AREA COLOGNE
Offline Offline
Edison Member
*
Karma: 21
Posts: 1125
I am 1 of 10 who understands binary
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
http://www.amazon.de/Tinxi-DSO203-Digital-Oszilloskop-deutsche-Anleitung/dp/B0058S22AA/
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
http://www.amazon.de/Velleman-Taschenoszilloskop-HPS-inkl-Tastkopf/dp/B004KKTUV6/

Gruß
Der Dani
Logged

So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

Pages: [1]   Go Up
Jump to: