Pages: 1 [2]   Go Down
Author Topic: Array Problem - Allgemeines Problem mit if in Verbindung von einem A-Sensor  (Read 2662 times)
0 Members and 1 Guest are viewing this topic.
Meran/BZ/IT
Offline Offline
Full Member
***
Karma: 0
Posts: 184
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

nene! Das dauert noch ein paar Monate.
Bin nur Opfer.
Aber was tut man nicht alles für seine Freunde!  smiley-grin
Logged

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

Jetz komm ich dahinter, danke euch zwein!

Ist viel produktiver, da ich nicht immer genau dort anfange zu morsen wenn ich nur alle 100ms den Wert abfrage. Da variiert der Punkt dann immer zwischen 1 und 3...

Werde das nun mal versuchen einzubauen.

Ich habe jetz noch 2 Probleme mit dem iPhone. Zum einen wird das erste Zeichen immer nur als minimalsten blitz ausgegeben (da die LED am iPhone auch erst warm werden / hochfahren etc muss ^^)

Daher würde ich vorschlagen, dass ein anfangs signal von so 1 sec als Start auch gehen würde. Damit wird dann die LED auf betriebstemperatur gebracht und der Arduino ist sich auch sicher, dass es jetz losgeht. Die jetzigen Methoden sind ja darauf aufgebaut, dass bei einem ersten Signal es dann auch schon losgeht, aber was macht der Aruino wenn jetz über 1 sec eingestrahlt wird und danach einfach nichts kommt? Gibt es für solche fälle dann Probleme oder gibt er einfach nur nichts aus?

Ich fände es so also praktisch wenn man am anfang und ende Start / End leuchten machen würde was so eine sec aufwärts sein könnte.

Das Zweite Problem ist, dass mein Programm von . auf - zicken macht und der Punkt dem Strich anscheinend etwas Zeit klaut und somit ein Punkt mit doppelter Pause und einem Punkt daraus entsteht. Wieso auch immer.. Das muss ich noch rausfinden. Denke es ist sinnvoller meine iPhone APP dementsprechend anzupassen als jetz den Arduino auf diesen Fehler anzupassen.


Mit "gespeicherter Zeichenfolge" meinst du dann meine Speichermethode mit dem Array und 4 Nullen??

Was meinst du mit "Das Array müsste Byte entsprechen" ??

Und die Morsetabelle sollte nichts verlangen, die sollte nur passiv aggieren und nicht aktiv oder hab ich da nen denk fehler?


Gruß
Flo

Logged

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

So iPhone App läuft jetz stabil mit folgenden werten: ein Punkt 0.5, eine Pause (zwischen Zeichen) 0.5 , ein Strich 1,5 und zwischen Wörtern auch 1,5 Pause (alles in Sekunden Angabe)

Da mach ich am besten alles was über 450 ms usw ist, da ich wahrscheinlich nicht in die bedingung " == 500 " schreiben kann was den äußeren Umständen echt weng hoch angerechnet währe wenn der exakt 500 messen würde smiley-grin


Jedenfalls hab ich noch eine Idee zum speichern der Werte:

Wir haben ja schon Byte x = 0b10101 = .-.- = Buchstabe (das ist die Methode von Michael_x)

Könnte man es nicht einfach so machen, dass man byte x = 0b1 initialisiert und dann bei wert 1 eine 0 hinten dran hängt und bei wert 2 eben eine 1.

Sprich sowas

Code:
x = x "+ 1" bzw "+ 0";

Nur will ich nicht den wert um eines erhöhen sondern hinten dran hängen. Das wird mit einem normalen Plus auf diese Weise nicht funktionieren ^^


Hab mich mal zu 2D Arrays kurz schlau gemacht, aber noch ein bis 2 fragen:

Am anfang muss man einen Datatype angeben, jedoch wird in den Zwei Ebenen ja jeweils ein anderer datatype verwendet (int bzw byte und char (für die buchstaben) )

Wie muss ich den dann definieren? Und in die erste Ebene schreibe ich dann meine Byte stränge rein. Nur werden dann bei zum beispiel bei dem buchstaben "e" der Byte strang so aussehen :   x = 0b10 ;

Das kommt dann in meine morsetabelle und wird am besten gleich so ausgegeben (??):

Code:
byte x = 0b1;
if (wert == 1){     // steht für punkt aus spaceball's idee zu den millis()
   x = x "+ 0";      // hinten dran hängen
}
Serial.print(morsetable[x]);


So sollte das Prinzip ausschauen:

Bei kurzen pausen wird einfach hochgezählt und eventuell bei über 4 ein Fehler ausgegeben.
Bei dreifacher Pause (nächstes Wort) Wird ein Befehl gegeben den Byte strang auszuwerten und zu Printen.
und bei Fünffacherpause wird eine neue Zeile Begonnen bzw Die Übertragung beendet, falls es über 4 sec lang sein sollte

Bräuchte jetz erstmal nur die Sache mit den Bytes und wie ob das so mit dem 2D Array funktioniert wie ich es in meinem kleinen Sample versucht habe zu veranschaulichen. smiley

Gruß
Flo

EDIT:

mein 2D Array schaut nun so aus: bei DIM_0_SIZE und DIM_1_SIZE wird wahrscheinlich die länge des Alphabets rein gehören? (--> 26)

Code:
byte char array [DIM_0_SIZE] [DIM_1_SIZE] = {
   //as many vals as dim1
  {0b101, 0b11000, 0b11010, 0b1100, 0b10, 0b10010, 0b1110, 0b10000, 0b100, 0b10111, 0b1101, 0b10100,
0b111, 0b110, 0b1111, 0b10110, 0b11101, 0b1010, 0b1000, 0b11, 0b1001, 0b10001, 0b1011, 0b11001, 0b11011, 0b11100},
  {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z}//as many rows as dim0
};
« Last Edit: January 26, 2013, 04:25:26 pm by mrlowalowa » Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3091
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Nur will ich nicht den wert um eines erhöhen sondern hinten dran hängen. Das wird mit einem normalen Plus auf diese Weise nicht funktionieren ^^
Richtig. Shiften nennt man die Operation, an die du denkst.

Code:
x = 1; // init
while ( true ) {
 byte i = getPunktStrichPause () ; // nur so als Pseudo-Code   ( 0 = .  /  1 = _   /  2 = Pause, mindestens die zwischen zwei Zeichen )
 if ( input < 2) x = (x << 1) | i;  // Shift um ein Bit nach links, neuer Punkt/Strich dazu
 else break; // Ende von while (true)
}

Statt des ODER ( | ) könntest du auch ein PLUS ( + ) verwenden, das ergibt hier dasselbe, da nur 0 oder 1 mit einer 0 verknüpft werden.
Logged

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

Das heißt ich habe jetzt das hier:

Code:
byte x = 0b00001;

Dann shifte ich die 1 um eins nach links und füge 0 bzw 1 hinzu was dann das hier ergeben sollte:

Code:
x = 0b00010;

Bei i gleich 2 oder höher würde dann die Umwandlung in einen Buchstaben statt finden oder zusätzlich weitere Aktionen, wie Zeilenumbruch etc


Dann exportiere ich meine Funktionen mal schön, damit das ganze etwas übersichtlicher wird und nehme die Variablen mit.

Der 2D Array müsste dann so passen nur fehlen jetz noch die ganzen 0 bei z.B. 0b10 ( = " . " ) ---> 0b00010

Dann sollte der Code auch funktionieren.


Habe meine Hardware nun auch um einen Button, 3 Status LED's in Grün, Gelb, Rot und einen Lautsprechererweitert. Mal schaun was sich aus meinem Kleinen Projekt noch so entwickelt smiley
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3091
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dein 2D Array mit 2*26 byte ist nicht kürzer als ein 1*32 Array, macht nur das Auswerten komplizierter und länger. ( Wenns schon läuft, ist es auch gut. )
Erst wenn du auch Morsecodes für Zahlen mitnimmst, hast du ein 1*64 Array mit einigen Lücken.

Wo kriegst du eigentlich die Morse-Signale her, dass du auf so strikte Zeiten vertrauen kannst ?

Übrigens:
0b101 und 0b00101 ist nur eine andere Schreibweise der gleichen Zahl. 

Logged

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

So um zum Array Problem zurück zu kommen: Hier bin ich nun  smiley-grin

Code:
byte array [26] [26] = {
    {0b00101, 0b11000, 0b11010, 0b01100, 0b00010, 0b10010, 0b01110, 0b10000, 0b00100, 0b10111, 0b01101, 0b10100,
    0b00111, 0b00110, 0b01111, 0b10110, 0b11101, 0b01010, 0b01000, 0b00011, 0b01001, 0b10001, 0b01011, 0b11001, 0b11011, 0b11100},
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26}
  };
  const char b_array[26] =  {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};

Kommt ein Fehler, dass const char [] zu viele Enterys hat...
Muss ich jetz splitten ?? Sprich wenn ausgabe aus array über 4 ist gehe in e-f_array etc? Oder gibt es da eine sinnvollere Lösung?

Kann euch auch mal gerne mein bisheriges werk präsentieren ^^

Code:
unsigned long time;
int sensor = A0,
    ma_count = 0, // Array Position hochzählen / zuweisen
    strich = 1,
    punkt = 0;
byte signal = 0,  // Signal ja/nein
     wert = 0,    // 0= Pause   1= Kurz   2= Lang   3= Zeilenwechsel
     code;

char ausgabe;

byte array [26] [26] = {
    {0b00101, 0b11000, 0b11010, 0b01100, 0b00010, 0b10010, 0b01110, 0b10000, 0b00100, 0b10111, 0b01101, 0b10100,
    0b00111, 0b00110, 0b01111, 0b10110, 0b11101, 0b01010, 0b01000, 0b00011, 0b01001, 0b10001, 0b01011, 0b11001, 0b11011, 0b11100},
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26}
  };
 const char b_array[26] =  {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};



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

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
    {char ausgabe;
    ausgabe = moersetable(code);
     Serial.print(ausgabe);
    }
     
     
  }
  if ( signal == 1 && analogRead(sensor)  <= 100)
  {
    signal = 0;
    time = millis();
    while ( analogRead(sensor) <= 100)
    {}
    if ( millis() - time > 450 ) // Lang
    { code = code << 1 | strich;}
    else // Kurz
    {code = code << 1 | punkt;}

  }
 
}

byte moersetable(byte code){
 
  // steht bereits im Head, aber kann hier vielleicht besser angebracht sein
 /* byte array [26] [26] = {
    {0b00101, 0b11000, 0b11010, 0b01100, 0b00010, 0b10010, 0b01110, 0b10000, 0b00100, 0b10111, 0b01101, 0b10100,
    0b00111, 0b00110, 0b01111, 0b10110, 0b11101, 0b01010, 0b01000, 0b00011, 0b01001, 0b10001, 0b01011, 0b11001, 0b11011, 0b11100},
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26}
  };
  const char b_array[26] =  {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
  */
  byte pos;
  char result;
  pos = array[code];
  result = b_array[pos];
  return result;
 
 
}

Und den Fehler Code den ich dazu bekomme:

Code:
Morse_Entschl_ssler_2:16: error: too many initializers for 'const char [26]'
Morse_Entschl_ssler_2.cpp: In function 'byte moersetable(byte)':
Morse_Entschl_ssler_2:72: error: invalid conversion from 'byte*' to 'byte'

Ich weiß auch noch nicht genau wie ich aus meinem 2D Byte Array dann eine positions angabe im Alphabet array machen kann.. :/

Gruß Flo[/code]
Logged

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

Code:
byte array [26] [26] = {
    {0b00101, 0b11000, 0b11010, 0b01100, 0b00010, 0b10010, 0b01110, 0b10000, 0b00100, 0b10111, 0b01101, 0b10100,
    0b00111, 0b00110, 0b01111, 0b10110, 0b11101, 0b01010, 0b01000, 0b00011, 0b01001, 0b10001, 0b01011, 0b11001, 0b11011, 0b11100},
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26}
  };
  const char b_array[26] =  {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
Und den Fehler Code den ich dazu bekomme:
Code:
Morse_Entschl_ssler_2:16: error: too many initializers for 'const char [26]'
Morse_Entschl_ssler_2.cpp: In function 'byte moersetable(byte)':
Morse_Entschl_ssler_2:72: error: invalid conversion from 'byte*' to 'byte'


Der Code enthält drei Fehler.
Code:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26}
sind 27 Einträge und nicht 26.
Code:
const char b_array[26] =  {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
Das sind Zeichenketten und keine einzelnen Zeichen. Du musst es so schreiben:
Code:
const char b_array[26] =  {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
Und zu guter letzt...
Code:
byte array [26] [26] = {
definiert ein Array mit 26 x 26 Zeichen. So wäre es richtig:
Code:
byte array [2] [26] = {
Logged

_______
Manfred

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3091
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Ich weiß auch noch nicht genau wie ich aus meinem 2D Byte Array dann eine positions angabe im Alphabet array machen kann.. :/
Dann lass es smiley-wink

- Ein byte array[26][26] ist nicht das was du willst, denn es bestünde aus 26*26 Elementen

- Ein eindimensionales Array für alle empfangenen Möglichkeiten von "." bis "----", wie ich es dir ganz am Anfang angedeutet habe, ist das einfachste.
  Das empfangene Morsezeichen ( z.B. a =  0b00101 ) kennzeichnet die Position in deiner Tabelle ( also 5 ) an welcher der auszugebende Buchstabe 'a' steht. Fertig.
  -- Lediglich die ersten 2 Einträge ( 0 und 1 ) gibt es nicht, da das kürzeste Zeichen e = 0b00010 ist.
       Du könntest die Morsetabelle bei e anfangen lassen und beim Zugriff immer diese 2 subtrahieren, aber das spart nichts.
  -- Du kannst diese Tabelle sogar einfach als text schreiben
     char morse[] = "??etianmsurwdkgohvf_l?pjbxcyzy.-"  ( nach http://www.opencaching.de/images/uploads/EE5E4A60-F7F2-11DF-B2AC-00163E3AC09B.jpg )
    
     morse[5] ist das Beispiel 'a'

  -- Mit Ziffern müsstest du nochmal 32 codes anfügen:  22 unbenutzte und die 10 Ziffern.    
Logged

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

Ah, danke für die Erleuchtung, euch beiden  smiley-wink

Hab jetzt noch ein bisschen rumbasteln und ausprobieren müssen und bin nun zu diesem Ergebnis in der Ausgabe gekommen:

Quote
rlo
?flo
???
e
?
?Xw
?f
e
?n?
e
o
?flo
?flo
?flo
?flo

Ich hab immer "flo" per Handy geschickt. Ab und zu staut sich da dann leider doch noch irgendwelche fehler an was dann zu den mittleren Ergebnissen geführt hat. Auch kommt es mal vor, dass mitten im f (..-.) ein e geprinted wird. (das liegt aber an der iPhone lampe die beim erst start immer erst kurz zuckt um "warm" zu laufen. Ist natürlich quatsch, dass sie warm laufen muss aber das ist bei jeder iPhone App mit LED Torch leider so, daher eher ein Hardware bzw Softwarefehler in der Firmware des iPhone. Wie dem auch sei... )

Erst ging es garnicht. Dann hab ich mir den Code nochmal von Michael_x angeschaut. Mit dem war ich von anfang an nicht ganz zu frieden, da ich Ihn nicht verstanden hab.. smiley-grin Irgendwas war mir da gleich am anfang nicht so ganz richtig.. Er hatte einen denkfehler mit dem Signal 1 und 0. Somit musste das "innere" / die Auswertung etc von punkt, pause, strich mit einander vertauscht werden, damit der Code überhaupt wirken kann.

Man kann ja keine pause messen und dann aus der Pause ein Zeichen ermitteln smiley-grin smiley-grin


Nachdem ich den Fehler gefunden hatte, wurde der letzte buchstabe nie ausgegeben, da mein Code in der while-Schleige hing... Daher hab ich nun in die while-Schleife die Ausgabe gesetzt, wenn die Zeit über einen gewissen rahmen (2 Sec) geht.
Kleiner nebeneffekt von code = 0b00001; in der while schleife war, dass mir dann immer ein Fragezeichen ausgegeben wurde. Deshalb wird der Befehl in der while-schleife nur ausgeführt wenn der code nicht gleich 0b00001 ist. So wurden tausende '?' erspart.

Jetz habe ich noch ein paar Falsch ausgaben zwischen drinn zu verzeichnen, was nach mehrmaligen drücken des Reset knopfes verschwindet.

Da würde es abhilfe schaffen am schluss (ebenfalls in der While-Schleife) alle Variablen etc auf 0 zu schalten.. Muss ich noch Testen.

Die übrigen Frage Zeichen die vom Code = 0b00001 in der whileschleife (höchst wahrscheinlich kommen) sind auch nicht grad supi.. Aber habe ich einfach unterdrückt durch die nicht Ausgabe von '?'

Nicht grad die feine Englische Art aber funktioniert.

was jetz noch fehlt ist die bereinigung des Codes der hier angesprochenen Fehler (variablen zurücksetzen) und ob vielleicht irgendwer noch grobe fehler entdeckt.

Hier nun mein Source Code smiley :

Code:
unsigned long time;
int sensor = A0,
    strich = 1,
    punkt = 0;
byte signal = 0,  // Signal ja/nein
     wert = 0,    // 0= Pause   1= Kurz   2= Lang   3= Zeilenwechsel
     code;

char ausgabe;

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

void loop()
{
  if ( signal == 0 && analogRead(sensor) > 100)
  {
    signal = 1;
    time = millis();
    while ( analogRead(sensor) > 100)
    {}
    if ( millis() - time > 450 ) // Lang
    { code = code << 1 | strich;
      //Serial.println("Strich");
    }
    else // Kurz
    {code = code << 1 | punkt;
     //Serial.println("Punkt");
    }
     
     
  }
  if ( signal == 1 && analogRead(sensor)  <= 100)
  {
    signal = 0;
    time = millis();
    while ( analogRead(sensor) <= 100)
    {
      if (millis() - time >= 2000 && code != 0b00001){
       char ausgabe;
       ausgabe = moersetable(code);
       if (ausgabe != '?'){
        Serial.print(ausgabe);
       }
       code = 0b00001;
       Serial.println("");
      }
 
    }
    if ( millis() - time >= 2000 )  // Pause 2 sec -> Zeilenumbruch
    {} // Zeilenumbruch
    if ( millis() - time >= 380)
    {wert = 3;} // Pause zwischen Signalen || braucht man nicht!!
    if (millis() - time >= 790)
    {wert = 4;
     char ausgabe;
     ausgabe = moersetable(code);
     if (ausgabe != '?'){
      Serial.print(ausgabe);
     }
     code = 0b00001;} // Pause zwischen Buchstaben
  }
 
}

byte moersetable(byte code){
 
  const char b_array[] =  {'?', '?', 'e', 't', 'i', 'a', 'n', 'm', 's', 'u', 'r', 'w', 'd', 'k', 'g', 'o', 'h', 'v', 'f', '_', 'l', '?', 'p', 'j', 'b', 'x', 'c', 'y', 'z', 'q', '.', '-'};
  char result;
  result = b_array[code];
  return result;
 
 
}


Gruß Flo[/code]
Logged

Pages: 1 [2]   Go Up
Jump to: