Sketches zusammenfügen

Hallo Community,

ich bin relativ neu in Sachen Programmierung etc.
Ich muss für eine Studienarbeit einen Prüfplatz mit entsprechender Software bauen.
Ich nutze für die Signalauswertung einen Ardunio. Mit diesem möchte ich über die Analogen Eingänge messwerte aufnehmen und mir in Labview anzeigen lassen. des Weiteren möchte ich über die digitlaen Ausgänge einen Rechtecktakt mit hoher Frequenz ( 1MHz ) ausgeben. ich habe zunächst beide Ansätze einzelnen versucht zu bewältigen und somit für jedes ein Programm bzw Sketch für meinen Arduni geschrieben.
Nun benötige ich eure Hilfe, weil ich beides in ein programm zusammenfügen möchte.
Könntet ihr mir evtl dabei helfen das ordentlich hin zu bekommen das evtl die Geschwindigkeit des Arduino nicht all so sehr beeinflusst wird. Habe mal versucht einfach alles einzufügen aber da hab ich dann oft einen Bluescreeen beim ausführen bekommen.

Das Problem, was ich beim einfachen zusammenfügen der Codes habe ist, wenn ich das Programm starte arbeitet es erstmal dauerhaft den Code 1 ab wie gewünscht…wenn ich dann aber eine taste Drücke die in Code 2 steht, wo ein Signal gesendet werden soll…stoppt die aufnahme aus dem ersten Code und wird dann auch nie mehr fortgeführt…erst wieder wenn ich das Programm beende und neu starte :confused:

Ziel ist also das dauerhaft Code 1 ausgeführt wird, wenn eine Taste die in Code 2 deklariert ist gedrückt wird, wird dieser solang sie gedrückt ist ausgeführt, anschließend soll aber wieder Code 1 ausgeführt warden dauerhaft…

Hier mal die beiden Codes

Code^1

const int sample = 2000;
unsigned long value0[sample];
unsigned long value1[sample];
unsigned long value2[sample];
unsigned long value3[sample];
unsigned long value4[sample];
unsigned long value5[sample];
 
void setup()
{
  //ADC setup
  adc_init(ADC, SystemCoreClock, 21000000UL, ADC_STARTUP_FAST); // Initialisierung ADC
  ADC->ADC_CHER = 0b0000000011111100; //Benutzte AD Kanäle auswählen
  ADC->ADC_MR &= 0b11111111000000001111111100000000;
  ADC->ADC_MR |= 0x80; //free running mode....ansonsten 0b00000000000100100000000000000000 für software trigger, high res, no sleep, not free running
 
  /*ADC->ADC_IER = 0b100; //enable interrupt
  ADC->ADC_IMR = 0b100; //enable interrupt in mask
 
  ADC->ADC_CR |= 0b10; //start first conversion*/
 
  analogReadResolution(8); // analogRead Befehl festsetzen auf 8Bit Übertragung
  Serial.begin(115200);
}
 
// the loop routine runs over and over again forever:
void loop()
{
while (!(ADC->ADC_ISR & 0b0000000011111100)); //wait for conversion to end
 
for(int i=0;i<sample;i++){
 
value0[i] = ADC->ADC_CDR[7]; //read daten A0
value1[i] = ADC->ADC_CDR[6]; //read daten A1
value2[i] = ADC->ADC_CDR[5]; //read daten A2
value3[i] = ADC->ADC_CDR[4]; //read daten A3
value4[i] = ADC->ADC_CDR[3]; //read daten A4
value5[i] = ADC->ADC_CDR[2]; //read daten A5
  }
for(int i=0;i<sample;i++){
 Serial.println(value0[i]);
 }
for(int i=0;i<sample;i++){
 Serial.println(value1[i]);
 }
for(int i=0;i<sample;i++){
 Serial.println(value2[i]);
 }
for(int i=0;i<sample;i++){
 Serial.println(value3[i]);
 }
for(int i=0;i<sample;i++){
 Serial.println(value4[i]);
 }
for(int i=0;i<sample;i++){
 Serial.println(value5[i]);
 }
}

Code^2

#define NOP __asm__ __volatile__ ("nop\n\t");
#define PAUSE NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP
#define PAUSEEND NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP
 
// 1 NOP Befehl entspricht 12ns (1/84MHz)
 
void setup() {
 
  pinMode(5, OUTPUT);
  Serial.begin(115200);  
  }
 
void loop() {
/*
on pin 5:
   FOR A: 1010 1010 1100 1100  
  FOR B: 1110 1110 1010 1010
  FOR C: 1010 0110 0110 1010
  FOR D: 1100 0011 1100 0011
*/
if(Serial.available()>0){
 
byte input = Serial.read();
Pio *p = digitalPinToPort(7); // Port.C
 
uint32_t s5 = digitalPinToBitMask(5);
uint32_t c5 = digitalPinToBitMask(5);
   
if(input==65){//A
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE
  }
 if(input==66){//B
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE  
  }
if(input==67){//C
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  }
if(input==68){//D
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE
  }  
 }
}

Wenn sie nicht gleichzeitig laufen müssen, sollte das gehen.

Wie hast du die zwei zusammengefügt?

Schonmal probiert, die Tastenabfrage in die Einzelsketche einzubauen ?
Also einfach zusätzlich

loop() {
if (digitalRead(Taster) == HIGH ) return;  // nichts tun wenn Taster falsch
...
}

kannst du dann deine Funktion unterbrechen / weiterlaufen lassen ohne Reset ?

Ne, also gleichzeitig muss es nicht sein...es soll halt nur code 1 das "Hauptprogramm" sein, das dann auch automatisch wieder ausgeführt wird, sollte man eine taste aus Code 2 in LabView gedrückt haben...

du meinst dein Code anstelle von meinem if (input == 65)...?

Das ganze wird ja über LabView angesterut, desswegen hab ich das so...das LabView beim drücken der Taste am Laptop ein "a" , "b", ... sendet und der sketch darauf reagiert..

oops, das (Taster) hatte ich falsch verstanden.

Nun musst du erzählen, wie labview das machen soll: ein Zeichen senden beim Drücken und ein anderes beim Loslassen "der Taste am Laptop" oder wie?

Also nochmal: "Wie hast du die zwei zusammengefügt?"

Schau den Teil rund um

if(Serial.available()>0){
 byte input = Serial.read();

an, und zeig das ...


aber da hab ich dann oft einen Bluescreeen beim ausführen bekommen

Probleme im kernel von deinem Laptop (falls du das mit bluescreen meinst), liegen entweder an labview oder deinem laptop Betriebssystem.

Also in meinem LabView Programm habe ich 4 Taster...(Signal 1 bis Signal4 heißen die )

Und wenn ich Signal 1 drücke, bleibt er so lange gedrückt bis ich in ein zweites mal drücke....evtl mach ichs später mit Latch, ma schauen...

Auf jedenfall, solange der Button "Signal 1" gedrückt ist, sendet er ein "A" an den arduino...wenn er nicht gedrückt ist, sendet er nix....

das if(Serial.available()>0)
habe ich einmgefügt weil ich es immer so gesehen hatte, ich aber glaub nicht zwingend erforderlich...

byte input ist ja einfach nur eine Deklaration, damit ich nachfolgend nicht immer mit Serial.Read() arbeiten muss.

Das erste zusammenfügen hab ich einfach ganz banal versuvvht indem ich in setup alles auch beiden Codes rein geschrieben habe und in der loop einfach nach dem ersten Code den zweiten mit mit dem if(Serial.available()>0) begonnen habe...

Auf jedenfall, solange der Button “Signal 1” gedrückt ist, sendet er ein “A” an den arduino…wenn er nicht gedrückt ist, sendet er nix…

wieviele ‘A’ / msec kommen denn da an ?
(Glaub ich nicht)

michael_x:
wieviele 'A' / msec kommen denn da an ?

das habe ich nicht gemessen/überprüft...

ich weis nur das es funktioniert also der einzelne code 2 mit dem LabView Programm dazu :slight_smile:

ich weis nur das es funktioniert also der einzelne code 2 mit dem LabView Programm dazu

Und wo ist das Problem, wenn du den Code^1 in den else Zweig packst ?

void loop() {
if(Serial.available()>0){
// Code 1

} else {
// Code 2
}
}

Code 2 erscheint mir unproblematisch, da die blockierenden Pausen extrem kurz sind. Etwas elaganter fände ich ein switch/case.

Code 1 macht sieben blockierende for-Schleifen mit je 2000 Durchläufen. Das dürfte etwas aufhalten. Ein for in loop ist sowas wie ein Looping. Du kannst aber loop anstelle von for nutzen, nur mußt Du das Zählen selbst übernehmen. Dann wird je i die loop durchlaufen und auch Code 1 bedient.

Da ich Deine Hardware nicht habe, hier ein abstrahierter Testsketch:

const int sample = 20; // Bei Dir 2000!
unsigned long value0[sample];
unsigned long value1[sample];
unsigned long value2[sample];
unsigned long value3[sample];
unsigned long value4[sample];
unsigned long value5[sample];

void setup()
{
  Serial.begin(115200);
  Serial.println("Anfang");
}

void loop()
{
  // Code 1
  static int i = 0;
  value0[i] = analogRead(A0); //read daten A0
  value1[i] = analogRead(A1); //read daten A1
  value2[i] = analogRead(A2); //read daten A2
  value3[i] = analogRead(A3); //read daten A3
  value4[i] = analogRead(A4); //read daten A4
  value5[i] = analogRead(A5); //read daten A5
  i++;
  i = i % sample;

  // Code 2
  if (Serial.available() > 0) {
    byte input = Serial.read();
    switch (input) {
      case 'A':
        Serial.println("Eingabe A");
        break;
      case 'B':
        Serial.println("Eingabe B");
        break;
      case 'C':
        Serial.println("Eingabe C");
        break;
      case 'D':
        Serial.println("Eingabe D");
        break;
    }
  }
}

Damit ist ein pseudo paralleler Ablauf möglich. Welche Auswirkungen das auf Deine sehr zeitkritische Aufgabenstellung hat, vermag ich nicht einzuschätzen. Alternativ könntest Du auch Code 1 bei default von switch/case einbauen, dann würde Code 1 nur ausgeführt, wenn keine Taste A bis D gedrückt ist.

t0bsN:
das if(Serial.available()>0)
habe ich einmgefügt weil ich es immer so gesehen hatte, ich aber glaub nicht zwingend erforderlich…

Nö, sonst mußt Du auf -1 abfragen.

t0bsN:
byte input ist ja einfach nur eine Deklaration, damit ich nachfolgend nicht immer mit Serial.Read() arbeiten muss.

Da read anders als peek den Zeiger verändert, könntest Du Serial.peek nutzen.

Welche Hardware hast Du denn?
Ich kenne nur einen Arduino mit mehr als 48000Byte RAM der produziert aber keine blaue Bildschirme.

Habe mal versucht einfach alles einzufügen aber da hab ich dann oft einen Bluescreeen beim ausführen bekommen.

Grüße Uwe

Ich danke für die Antworten :slight_smile:

Werde mich jetzt mal dran setzen und alles testen und danach berichten :slight_smile:

Ich nutze einen Arduino Due.

edit:

Also das mit dem Staic int I…und selbst zählen da bringt er mir eine Fehlermeldung:

I does not name a type und expected unqualified-id before ‘for’

Die ausgabe in den for schleifen die kann ich aber beibehalten ? weil das oben in dem testskech fehlt ? und die ausgabe für die einzelnen cases?

ich hang es am besten mal an , so wie ich es jetzt habe…

aber er hängt sich immernoch auf, bzw nachdem ich ein Signal (a,b,c, oder d9 sende fährt er nicht mit dem Code 1 8messen) fort :confused:

#define NOP __asm__ __volatile__ ("nop\n\t");
#define PAUSE NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP
#define PAUSEEND NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 

// 1 NOP Befehl entspricht 12ns (1/84MHz)
const int sample = 2000;
unsigned long value0[sample];
unsigned long value1[sample];
unsigned long value2[sample];
unsigned long value3[sample];
unsigned long value4[sample];
unsigned long value5[sample];

void setup() {
  //ADC setup
  adc_init(ADC, SystemCoreClock, 21000000UL, ADC_STARTUP_FAST); // Initialisierung ADC
  ADC->ADC_CHER = 0b0000000011111100; //Benutzte AD Kanäle auswählen 
  ADC->ADC_MR &= 0b11111111000000001111111100000000;
  ADC->ADC_MR |= 0x80; //free running mode....ansonsten 0b00000000000100100000000000000000 für software trigger, high res, no sleep, not free running
  
  /*ADC->ADC_IER = 0b100; //enable interrupt
  ADC->ADC_IMR = 0b100; //enable interrupt in mask

  ADC->ADC_CR |= 0b10; //start first conversion*/
  
  analogReadResolution(8); // analogRead Befehl festsetzen auf 8Bit Übertragung
  
  
  pinMode(5, OUTPUT); 
  Serial.begin(115200);  
              }

void loop() {
  
while (!(ADC->ADC_ISR & 0b0000000011111100)); //wait for conversion to end 

for(int i=0;i<sample;i++){
  
value0[i] = ADC->ADC_CDR[7]; //read daten A0
value1[i] = ADC->ADC_CDR[6]; //read daten A1
value2[i] = ADC->ADC_CDR[5]; //read daten A2
value3[i] = ADC->ADC_CDR[4]; //read daten A3
value4[i] = ADC->ADC_CDR[3]; //read daten A4
value5[i] = ADC->ADC_CDR[2]; //read daten A5
     }
for(int i=0;i<sample;i++){
 Serial.println(value0[i]);
 }
for(int i=0;i<sample;i++){
 Serial.println(value1[i]);
 }
for(int i=0;i<sample;i++){
 Serial.println(value2[i]);
 }
for(int i=0;i<sample;i++){
 Serial.println(value3[i]);
 }
for(int i=0;i<sample;i++){
 Serial.println(value4[i]);
 }
for(int i=0;i<sample;i++){
 Serial.println(value5[i]);
 }
  
/*
on pin 5: 
	FOR A: 1010 1010 1100 1100  
        FOR B: 1110 1110 1010 1010
        FOR C: 1010 0110 0110 1010
        FOR D: 1100 0011 1100 0011
*/
if(Serial.available()>0){ 

byte input = Serial.read();
 
Pio *p = digitalPinToPort(7); // Port.C

uint32_t s5 = digitalPinToBitMask(5);
uint32_t c5 = digitalPinToBitMask(5);
    
switch (input){
  case 'A':
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE 
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE
  break;
  case 'B':
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE  
  break;
  case 'C':
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE 
  p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE 
  p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE 
  p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE 
  break;
  case 'D':
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE 
  p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE
  p->PIO_CODR = c5; PAUSE p->PIO_CODR = c5; PAUSE p->PIO_SODR = s5; PAUSE p->PIO_SODR = s5; PAUSE 
  break;  
 }
}
}

I does not name a type und expected unqualified-id before 'for'

Ich sehe kein[b]  I  [/b], das als Datentyp missverstanden werden könnte.
Das mit dem "und" ist eine andere Fehlermeldung und das "und" stammt von dir oder ist das Teil derselben Fehlermeldung?
Hast du Zeilennummern zu diesem Fehler / diesen Fehlern ?

ja, also das sind 2 Fehlermeldungen…
die treten halt nur auf wenn ich meine for schleife weg nehme (for(int i=0;i<sample;i++))und dafür das static int I nehme und dann i++; und i = i % sample; hinter das sammeln der daten…

mit der for schleife , so wie der Code oben steht, funktioniert alles…

was das fortführen von Code 1 betrifft, ich denke mein Problem liegt in LabView , da ich 2 Registerkarten erstellt hatte…

Ich werde es mal versuchen alles in eine while schleife zu Packen im LabView Programm…

Iundisind auf jeden Fall zwei verschiedene Variable.

mit der for schleife , so wie der Code oben steht, funktioniert alles...

Dann lassen wir es mal so, ausser du wirst etwas konkreter in deiner Frage.

ich denke mein Problem liegt in LabView , da ich 2 Registerkarten erstellt hatte...
Ich werde es mal versuchen alles in eine while schleife zu Packen im LabView Programm...

das muss ich jetzt auch nicht verstehen, hoffe ich.

michael_x:
Iundisind auf jeden Fall zwei verschiedene Variable.

Das es es ausversheen groß gemacht in der Rechtschreibkorrektur, sorry :smiley:

das muss ich jetzt auch nicht verstehen, hoffe ich.

Ich weiß ja nicht, inwiefern LabView bekannt ist ? :slight_smile: aber Dort ist es so das man den gesamten "code" bzw die verwendetetn Bausteine in eine while schleife setzen muss, damit alles dauerhaft ausgeführt wird, bis man den STOP Button drückt :smiley:


Also soweit funktioniert es jetzt auch, einziges "Problem": Da ich das Visa-Element Write nehme um die Variable für den Code 2 zu senden, wartet das Programm jetzt immer bis ich einen Knopf gedrückt habe für ein Signal und führt dann den Code 1 genau 1mal aus....danach wartet er wieder auf ein Input wegen dem "write" Element...

Kennt sich damit zufällig jmd aus, wie man es umgehen kann ? Ansonsten muss ichs mal im LabView Forum versuchen :slight_smile: