Go Down

Topic: Arduino Oszilloscope bauen (Read 1 time) previous topic - next topic

Rudi01

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: [Select]
/*
* 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.

uwefed

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

Rudi01

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

jurs


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.

Eisebaer

hi,

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

gruß stefan.
nimm abblockkondensatoren!  100nF.  glaub mir, nimm abblockkondensatoren!

uwefed

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

Rudi01

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

uwefed

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

volvodani

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
So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

Go Up