Pages: [1] 2   Go Down
Author Topic: Array Problem - Allgemeines Problem mit if in Verbindung von einem A-Sensor  (Read 1957 times)
0 Members and 1 Guest are viewing this topic.
Deutschland
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

Vorab hier mal mein Code.

Habe vor an einer Fotozelle kurze und Lange Signale (Morsesignale) abzufragen.

Das abfragen an der Fotozelle klappt super und Punkte erkennt er mir auch ^^

Das aller erste problem ist jedoch, dass er gerne nur Punkte ausgibt...

Müsste ich jetz für einen "Strich" i auch genau definieren, da es ja mit i > 3 leider nicht klappt..



Code:
int count = 0;
int sensor = A0;
int i;
int c;
//int array[];

void setup(){
  Serial.begin(9600);
  i = 0;
  c = 0;
}

void loop() {
 
  int sensorValue = analogRead(sensor);
 
  if(sensorValue <= 100){
    count = 0;
  }
 
  if (sensorValue >= 100){
    i = i + 1;
  }
 
  if (i == 3 && count == 0){
   // array[c] = ".";
    c = c + 1; 
    i = 0;
    Serial.println ("Punkt");
  }
   
  if (i > 3 && count == 0){
   // array[c] = "-";
    c = c + 1;
    i = 0;
    Serial.println ("Strich");
  }
 
  delay(100);
 
}

Habe auch schon das Hier versucht was auch nur Punkte ausgibt:

Code:
int count = 0;
int sensor = A0;
int i;
int c;
//int array[];

void setup(){
  Serial.begin(9600);
  i = 0;
  c = 0;
}

void loop() {
 
  int sensorValue = analogRead(sensor);
 
  if(sensorValue <= 100){
    count = 0;
  }
 
  if (sensorValue >= 100){
    i = i + 1;
  }
  if (i >3){
    if (i > 3 && count == 0){
     // array[c] = "-";
      c = c + 1;
      i = 0;
      Serial.println ("Strich");
    }
  }
  else {
    if (i == 3 && count == 0){
     // array[c] = ".";
      c = c + 1; 
      i = 0;
      Serial.println ("Punkt");
    }
  }
   
 
   
 
  delay(100);
 
}

Das ist mein eines Problem,

das andere ist, dass ich mein ergebnis nun in irgendeiner Form am stück speichern möchte um es dann am schluss auszulesen und in klartext wie "hallo" oder aber auch sätzen wieder zu geben. Dabei habe ich an einen Array gedacht.

Das gegenstück zu diesem Progamm befindet sich auf meinem iPhone mit dem ich über einen NSMutablArray einen "Array" mit unbestimmter länge erzeugen konnte und so einfach x beliebig lange Arrays haben konnte.

Dummerweise muss ich hier die länge des array's angeben..

Habt ihr da vielleicht eine Idee / Vorschlag wie man dafür eine Lösung findet??


Noch dazu bin ich im besitz eines Ethernet shilds und Arduino Uno, wobei ich eventuell als Auslagerung eine SD karte einschieben könnte wenn der Platz nicht reicht, was ich aber nicht glaube  smiley-mr-green

Schon mal Vielen dank für eure Hilfe!  smiley-wink
Logged

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

Dein Programm funktioniert nicht, da zuerst die Bedingung für Punkt wahr wird und die Variablen zurückgesetzt werden und dann nie die Werte für einen Strich erreicht werden.
Noch 2 Fehler.
Um die Länge des Impulses zu Kontrollieren mußt Du die Zeit messen. Dein Programm mißt die Intensität des Impulses.
Verwende ein Digitales Pin und einen Fototransistor. Ein Fotowidertand ist zu langsam.
Grüße Uwe
Logged

Deutschland
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Das habe/ wollte ich eben verhindern durch das if (i == 3 && count == 0)

also sollte die Punkt Bedingung nur eintreten, wenn Drei Werte über 100 waren und nun unter null ist..

Ich glaub der Fehler liegt darin, dass ich count bei Sensor Value über 100 dann auch auf 1 etc setzten muss, da dieser Wert sonst ja immer bleibt..

Okay ich suche mir mal was mit der Zeit. Ich hatte es davor so geregelt, dass nur alle 100ms der Wert abgefragt wird und ein Punkt eben 3 x 100 ms sind. Dadurch habe ich die Zeit indirekt schon abgefragt.

Habe solch einen Fototransistor wie auf dem Bild zu sehen ist.



Das habe ich auch vor (Die intensität zu messen), da in einem Normalen Raum bereits die Intensität sich in einem bereich zwischen 0 und 100 bewegt ( i.d.R. bei mir 30-50 ) Und wenn ich eben eine Taschenlampe (die App) direkt rein leuchten lasse ist der Wert weit über 100

Daher ist mir ein Analoger Pin eigentlich schon lieber.

Die frage ist nur, wie ich das jetz nun Speichern kann?

Ich könnte einfach mehrere Arrays bzw einen Großen erzeugen und mit foo voll schreiben bzw leer lassen und am schluss dann die leeren Speicher Löschen bzw Ignorieren. Ginge das?

MfG

EDIT: Habe gerade bei if (sensorValue >= 100) noch count = count + 1; eingefügt und ich kann nun Punkte und Striche unterscheiden smiley

Jetz ist das nächste eben der Array oder eine andere Art des Speicherns gefragt.. (Siehe den auskommentierten Code)

EDIT2: keiner eine Idee??
« Last Edit: January 23, 2013, 03:51:58 pm by mrlowalowa » Logged

Deutschland
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Push !
Logged

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

ich hatte Dir schon geantwortet.
Logged

Deutschland
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich kann nun aber schon Striche und Punkte gesondert voneinander erkennen mit meiner Methode

Was jetz fehlt ist die Speicherung des wertes, worauf du mir noch nicht geantwortet hattest.

Da war ja eben die Idee eines Arrays jedoch kann ich nur bestimmte längen eingeben..

MfG
Logged

Germany
Online Online
Faraday Member
**
Karma: 49
Posts: 2757
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich kann nun aber schon Striche und Punkte gesondert voneinander erkennen mit meiner Methode
Glückwunsch. Auch die Pausen zwischen zwei Buchstaben ?
Quote
Was jetz fehlt ist die Speicherung des wertes, worauf du mir noch nicht geantwortet hattest.
Da war ja eben die Idee eines Arrays jedoch kann ich nur bestimmte längen eingeben..
Das stimmt, der RAM des Arduino ist begrenzt.
Wie lange soll der Arduino laufen? Warum speichern, wenn du's schon zum PC übertragen hast?
Edit : Sorry, hab dein ersten Post nicht sorgfältig genug gelesen.
Fehlt ja noch die Erkennung der Morsezeichen.
Aber dafür reicht doch ein Array von 5 (?) Byte, oder so.
Schwieriger ist vermutlich das dekodieren.

Was hältst du davon: Punkt ist 0, Strich ist 1, und jedes Zeichen fängt mit einer 1 an, damit man die Länge erkennt.
Das ganze wird in ein Byte geshiftet, und daraus ein Zeiger auf die Ergebnistabelle gemacht
e = . = 0b00010  = 2
t = - = 0b00011  = 3
i = .. = 0b00100  = 4
a = .- = 0b00101  = 5
usw.

Das ist nicht speicheroptimiert, aber 64 byte solltest du haben.

//                           0    1    2    3    4    5     ...                                   
const char morsetable[] = { '?', '?', 'e', 't', 'i', 'a' ,  // ... usw   
};
 

« Last Edit: January 24, 2013, 04:14:08 pm by michael_x » Logged

Deutschland
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Pause hat mich nun gereitzt  smiley-roll

Habe nun die drei Pausen Typen eingebaut und auch Erkennung wann das ganze anfängt und wieder aufhört.

Hab auch jeweils was in die Kommies zur Erklärung dazugeschrieben.

Code:
int count = 0;
int sensor = A0;
int i;
int c;
int pause;
int start_pause;
int count_p;

//int array[];

void setup(){          // initialisierung meiner int's
  Serial.begin(9600);
  i = 0;
  c = 0;
  pause = 0;
  start_pause = 0;
  count_p = 0;
}

void loop() {
 
  int sensorValue = analogRead(sensor); // Abfragen des Fototransistors
 
  if(sensorValue <= 100){               // Wenn kein Licht bzw Steulicht von Raum etc
    count = 0;
    if (start_pause == 1){              // Beginnt erst, wenn schon einmal Licht war
      if (pause == 0){                  // Wenn Pause zurückgesetz wurde, dann mitzählen
        count_p = 0;
      }
      pause = pause + 1;               
      count_p = count_p + 1;            // Kann das eventuell rausgelassen werden? nur für letzte funktion   
    }
   
  }
 
  if (sensorValue >= 100){
    i = i + 1;
    count = count + 1;
    start_pause = 1;
   
  }
  if (i > 3 && count == 0){
     // array[c] = "-";
     c = c + 1;
     i = 0;
     pause = 0;
     Serial.println ("Strich");
   }
   if (i == 3 && count == 0){
     // array[c] = ".";
     c = c + 1; 
     i = 0;
     pause = 0;
     Serial.println ("Punkt");
    }
   
   if (i == 1 && pause == 3 && start_pause == 1){
     pause = 0;
     Serial.println("Pause Buchstabe");            // Zwischen jedem Buchstaben ist eine Punkt länge Pause
   }
   if (i == 1 && pause == 6 && start_pause == 1){
     pause = 0;
     Serial.println("Pause Wort");                // Zwischen jedem Wort sind zwei Punkte bzw ein Strich Pause
   }
   if (i == 1 && pause == 9 && start_pause == 1){
     pause = 0;
     Serial.println("Pause Satz");                // Zwischen jedem Satz sind 3 Punkt-längen Pause
   }
 
   if (count_p >= 10){
     start_pause = 0;                          // Damit keine unnötigen Pausen gezählt werden
     count_p = 0;                              // Zurücksetzten
     
     Serial.println ("Übertragung Abgeschlossen"); // Könnte dem Array / Plotter sagen: jetz umwandeln
   }
 
  delay(100);                        // Fragt nur alle 100 ms den Wert am Sensor ab
 
}


Die jetzigen Serial.println sind nur zum Testen da, damit man sieht, dass was ankommt.


Ich find die Idee super! smiley smiley

Nach deinem Prinzip müsste dann das hier stimmen: (Zwecks Verständniss)

u = ..- = 0b01001
q = --.- = 0b11101

ß = ...--.. = 0b10001100 (Das würde jetz aber den Ramen von max 4 Zeichen sprengen, wegen Sonderzeichen)

Das ß könnte man aber auch erstmal auslassen ^^ Das sind Träumereien aber cool wäre es schon.

Habe übrigens 32.256 Bytes Platz, also könnte man sich da ruhig austoben smiley-wink

Das Problem ist dann aber immernoch die Speicherung?

Achsoooo... ich kann die Dann ja alle hintereinander in einer Line im Serial Port ausgeben lassen und dann bei neuer eingabe in die nächste Zeile springen. smiley Jetz kapiere ich auch deine aussagen vor dem Edit.


Wie erzeugt man bei Arduino Object C einen Pointer? Hab die bisher nur beim iPhone gemacht..

Momentan spielt sich bei mir alles im void loop() ab, dafür will ich ja aber eine weitere "Funktion" oder sehe ich das falsch?


Schon mal danke für den Super Tipp!! smiley smiley
Logged

Germany
Online Online
Faraday Member
**
Karma: 49
Posts: 2757
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dein Verständnis ist richtig.
Glaube nicht dass Samuel Morse ein 'ß' gekannt hat. (Edit: bzw sowas exotisches übertragen wollte) Kommt noch nicht mal in ASCII vor.

Quote
Wie erzeugt man bei Arduino Object C einen Pointer? Hab die bisher nur beim iPhone gemacht..
Weiss nicht was das mit "Object" zu tun hat. Pointer sind was ganz normales bei c.
Brauchst du aber noch nicht mal.
Wenn du deine Morsesignale entschlüsselt hast und z.B.
Code:
byte x = 0b1001;  // wir haben "..- " empfangen und das Zeichen ist fertig
char z = morsetable[x]; // der Inhalt von morsetable[17] ( 'u' ) ist jetzt in z
Serial.print(z);

Mit Pointern sähe das so aus
Code:
char* zp = morsetable+x;
Serial.print( *zp );

Edit: P.S.
Quote
Habe übrigens 32.256 Bytes Platz, also könnte man sich da ruhig austoben
Z.Zt. liegt eine Kopie der morsetable im RAM, und der ist beim UNO nur 2k gross.
Da die Tabelle konstant ist, könntest du sie auch aus dem Flash-Speicher lesen ( PROGMEM ), aber wenn's auch so geht, warum ?

Ich versteh nicht, was du auf dem Arduino speichern willst:
Nach der Zeichen-Pause kannst du ein Zeichen dekodieren und ausgeben.
Bei der Wort-Pause gibst du ein extra Leerzeichen aus.
Bei der Satz-Pause gibst du ein extra Newline  ( '\n' )
Nach 10 Pausen Ruhe ( oder eher deutlich später ) kommt "Übertragung beendet".
Arduino hat und braucht hierfür kaum Speicher.
« Last Edit: January 25, 2013, 04:05:55 am by michael_x » Logged

Meran/BZ/IT
Offline Offline
Full Member
***
Karma: 0
Posts: 184
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,
hab mir mal eine Idee mit millis() ausgedacht (aber nicht getestet):
Code:
unsigned long time;
int sensor = A0,
    sensorValue = 0;
byte signal = 0,  // Signal ja/nein
     wert = 0;    // 0= Pause   1= Kurz   2= Lang   3= Zeilenwechsel

void setup()
{
  Serial.begin(9600);
  // time = millis();
}

void loop()
{
  if ( signal == 0 && analogRead(sensor) > 100)
  {
    signal = 1;
    time = millis();
    while ( analogRead(sensor) > 100)
    {}
    if ( millis() - time >= 2000 )  // Pause 2 sec -> Zeilenumbruch
    { wert = 3; } // Zeilenumbruch
    else
    { wert = 0; } // Pause
  }
  if ( signal == 1 && analogRead(sensor)  <= 100)
  {
    signal = 0;
    time = millis();
    while ( analogRead(sensor) <= 100)
    {}
    if ( millis() - time > 300 )
    { wert = 2; } // Lang
    else
    { wert = 1; } // Kurz
  }

Damit kannst Du die Zeitspannen exakt bestimmen.
Vielleicht hilfts Dir ja ein bischen....

Gruß
Reinhard
« Last Edit: January 25, 2013, 05:24:33 am by spaceball » Logged

Meran/BZ/IT
Offline Offline
Full Member
***
Karma: 0
Posts: 184
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

.... einen hab ich noch.....  ;-)
Eigentlich sind bei analogRead<=100 3 Zustände vonnöten:
<300 Zeitspanne zwischen einem Piep und dem nächsten
300-2000 Leerstelle, löst gleichzeitig einen Abgleich der letzten Signale mit dem Zeichen-Array aus. Ausgabe des Zeichens mit Serial print
>2000 Zeilenumbruch

Gruß
Reinhard

Logged

Deutschland
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@michael_x:

Da geb ich dir Recht smiley-grin Wäre nur schön gewesen, da ich ein solches Zeichen in meinem Name trage und das dann noch ne Spur eindrucksvoller wirken würde smiley-razz (ist aber wie gesagt nur eine Spielerei smiley-wink )

Das Object kommt eben vom iPhone App programmieren. Aber mir ist auch gerade aufgefallen, dass ich gar nicht mit Objekten zu tun habe (sprich [blablalba] ).

Ich versteh nicht, was du auf dem Arduino speichern willst:
Nach der Zeichen-Pause kannst du ein Zeichen dekodieren und ausgeben.
Bei der Wort-Pause gibst du ein extra Leerzeichen aus.
Bei der Satz-Pause gibst du ein extra Newline  ( '\n' )
Nach 10 Pausen Ruhe ( oder eher deutlich später ) kommt "Übertragung beendet".
Arduino hat und braucht hierfür kaum Speicher.

Was ich Speicher will ist das was du auch vergessen hast oder ich den vielleicht selbstverständlichen Weg nicht weiß.

Um die Zeichenfolge " . . - " entschlüsseln zu können musst du die Zeichenfolge erst einmal Speichern bzw zusammen schieben.

Das stelle ich mir nun aber eher "einfach" vor. Man könnte einen Array mit 4 bzw 3 (wegen der 0 Speicherfläche ?? ) erzeugen und mit 0 o.ä. füllen. Wenn jetz ein Punkt kommt den Platz mit 1 vollschreiben und bei Strich eben mit 2. Um dann etwas zusammen geschobenes auszugeben lässt man die Nullen eben "fallen" und schreibt den Array dann wieder mit Nullen voll damit kein Fehler für die nächsten Zeichen übrig bleibt.



@spaceball:

Danke für deine Überlegungen! Die werde ich auch mal ausprobieren! smiley-wink
int sensorValue hast du anscheinend initialisiert aber nie gebraucht und kann deshalb weggelassen werden?

millis() - time verstehe ich auch nicht so ganz vom Prinzip her. Dachte time = millis() .

Das wäre ja dann das gleiche wie " x - x " und das ist immer null.

Von daher müsste man 2 unterschiedliche Zeiteinheiten parralel laufen lassen und deren Differenz würde dann dem hier entsprechen oder sehe ich das falsch?

Ich frage mich nur wann dann die andere Zeit einheit anfagen soll. Da man dann aufgrund der schon gelieferten Zeichensätze zusätzlich Zeit mit einberechnen müsste, welche ja variieren und daher meinen Ausgaben am Schluss noch ein verbrauch_time = XY machen müsste abhängig von den punkten und Strichen.


Danke auf jedenfall schon mal euch beiden für eure Super Unterstützung!!!! smiley smiley smiley


Gruß
Flo
« Last Edit: January 25, 2013, 12:47:59 pm by mrlowalowa » Logged

Munich/Germany
Offline Offline
God Member
*****
Karma: 9
Posts: 642
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

millis() liefert die Anzahl der Millisekunden zurück, die seit dem starten des Arduino vergangen sind. Daher ändert sich der Wert ständig.
Mit time = millis() merkst Du dir den aktuellen Wert. Mit millis() - time bekommst Du die Millisekunden, die seit dem Merken vergangen sind.
Logged

_______
Manfred

Meran/BZ/IT
Offline Offline
Full Member
***
Karma: 0
Posts: 184
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo mrlowalowa,
tja, das sensorValue ist wirklich  umsonst. Hatte ich am Anfang anstatt "signal" gedacht.

time= millis();
damit nehme ich den aktuellen Wert der hochgezählten Zeitvariablen ( wie von MaFu beschrieben... Danke! ).
Dann warte ich mit der while-Schleife solange, bis sich der Sensorzustand von Licht zu Dunkel oder umgekehrt ändert und lese dann noch mal die Zeítvariable aus.
Nun ergibt die Differenz die Länge des Signals: entweder des Lichtsignals oder der Pause!
Somit kann ich auch gleich zwischen Kurz oder Lang und zwischen Leerzeichen, Zeilenumbruch und "Signalzwischenraum" unterscheiden.

Natürlich bleibt das Programm in der while-Schleife hängen, solange sich  der Sensorzustand nicht ändert.
Dies sollte aber in Deinem Fall kein Problem darstellen.

Wegen dem Array:
Wenn ich meinem Beispiel folge, würde die 0 den Vergleich starten, der die gespeicherte Signalfolge mit der in einem mehrzeiligen 2D-Array gespeicherten Buchstabentabelle abgleicht und darin den entsprechenden Eintrag ermittelt.
Das Array müßte Byte entsprechen, da es 2 Signal-Zustände  gibt (Kurz und Lang) und eben noch den "da kommt nichts mehr Zustand" (Array-Wert = z.B. 255 oder auch 0 ...), falls die Morsetabelle nur ein kurzes Piep verlangt...

Gruß
Reinhard

PS.: Ich entschuldige mich im Voraus, falls meine grauen Zellen meine Überlegungen etwas verwirrend formuliert haben sollten, aber um 1:40 Uhr und nach mehreren Geburtstagsfeierbierchen läufts einfach nicht mehr ganz so rund....
 smiley-lol
Logged

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

Du hast Geburtstag und sagst mir nichts?
Alles Gute!
Logged

Pages: [1] 2   Go Up
Jump to: