PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Eine 8 stellige Zahl auswerten



Chevy
25.03.2015, 01:23
Hi,

ich weiß, das viele der Experten hier, sehr allergisch reagieren, wenn jemand schreibt "Ich habe ein Problem" und im endeffekt damit meint: "Wer löst mir mein Problem" bzw. "wer schreibt mir meinen Code"

Bei meinem Problem geht es nicht darum, dass mir jemand meine Arbeit abnimmt, sonder mich vielleicht auf den richtigen Weg bringen kann.

Also es geht darum das ich ein Projekt habe, wo verschiedene Arduinos getrennt arbeiten werden. Diese jedoch miteinander über Funkt kommunizieren sollen. Als erstes dachte ich mir, das die Anweisung, der Arduinos die meine Anzeige ansprechen wollen, über einen 8 stellige Zahl erfolgen soll. Nun muss der Empfänger diesen 8 stelligen Zahl auswerten und zwar jede der acht Stellen einzel. Damit ich dann später jeder Zahl eine Aufgabe zuweisen kann. Da es sich beim Empfänger um eine 13 Segment (pro Ziffer) Anzeige handelt die insgesammt 5 Ziffern besitzt und dazu noch einen Doppelpunkt und einen einzelnen Punkt sowie eine Möglichkeit den Ziffern entweder als Km/h oder Sek zu deklarieren, dachte ich das der Code mit den 8 stelligen Zahl eigentlich ganz gut ist.

Habe mir daher mal folgendes Programm ausgedacht, welches auch funktioniert. Ihr könnt es selber testen und es verändern z.B. eine andere Beispiel Zahl einsetzen oder die Beispielzahl automatisch um 1 erhöhen lassen und damit die Anzeige nicht so schnell scrollen, kann man die Pausen wieder aktivieren.

Meine Frage ist jetzt an die Experten: Ist das so in Ordnung oder mache ich es mir viel zu kompliziert bzw. gibt es einfachere Lösungsansätze?

Gruß Marco




/*
*
* Copyright (c) 2015 Marco Steinhauser. All rights reserved
*
* Anzeige
* Dieses Test Programm ist für die Anzeige DRAG Race
*
*
* getestet auf Arduino Uno R3
*
*
* Version 1.0
* Erstellt Vers. 1.0 am 24 März 2015
* V. 1.0 Eine 8 stellige Zahl wird in einzelnen Zahlen aufgeteilt
* Zur kontrolle der Funktion wird das Ergebnis auf den
* Seriellen Monitor ausgegeben.
*/

long zahl=12345678; //Beim Durchlauf mit +1 hier 9999999 eintragen.

int zahla=0;
int zahlb=0;
int zahlc=0;
int zahld=0;
int zahle=0;
long zahlf=0;
long zahlg=0;
long zahlh=0;


void setup()
{

Serial.begin(9600);

}

void loop()
{

//delay(500);

//zahl = zahl++; //Zahl bei jedem Durchlauf um 1 erhöhen

Serial.println("");
Serial.print("Zahl Vorgabe="); Serial.println(zahl);

//delay(200);
bestimmeZahl();

}

void bestimmeZahl () // Funktion zum Auswerten einer 8 stelligen Zahl
{

/************************************************** ******************
Beispiel Zahl ist = 12345678
Zur bestimmung der ersten Ziffer wird die Zahl durch 10000000 geteilt.
Das Ergebnis wäre dann 1,2345678. Da jedoch die Variable "int" bzw.
"long" nur Ganzzahlen dasrstellen können ist das Ergebnis der ersten
Ziffer eine 1. Also erste Zahl "zahla" = 1
************************************************** *******************/

zahla=(zahl/10000000);// Die erste Zahl bestimmen

//Serial.print("Zahl A ="); Serial.println(zahla);

//delay (200);

/************************************************** *********************
Beispiel Zahl ist = 12345678
Zur Bestimmung der zweiten Ziffer wird als erstes die Zahl durch
1000000 (Also durch 1 mit 6 nullen, statt wie oben eine 1 mit 7 nullen)
geteilt. Das Ergebnis wäre dann 12,345678. Das Ergebnis, dass in die
Variable "zahlb" geschrieben wird ist eine 12
************************************************** **********************/


zahlb=(zahl/1000000); // Zweite Zahl bestimmen


/************************************************** *********************
Beispiel Zahl ist = 12345678
Zur Bestimmung der zweiten Ziffer wird nun das Modulo der Zahl in der
Variable "zahlb" bestimmt.
Modulo ist die sogenante Restklassenrechnung. Hier wird der Rest
einer Division berechnet. Die Formel lautet a = 10 * b + c oder in diesem
Fall "zahlb" = 10 * b + c
Bei Modulo mit 10 ist es immer die letzte Ziffer.

a = die Zahl die gegeben ist, also hier 12
b = die Zahl wie oft die 10 in die 12 passt, also hier 1
c = der Wert der Differenz zwischen a und 10, also hier 12-10=2

Also der Wert von "zahlb" ist somit 2.
************************************************** **********************/

zahlb=(zahlb%10);

//Serial.print("Zahl B ="); Serial.println(zahlb);

//delay (200);

/************************************************** *********************
Beispiel Zahl ist = 12345678
Zur Bestimmung der dritten Ziffer wird als erstes die Zahl durch
100000 (Also durch 1 mit 5 nullen, statt wie oben eine 1 mit 6 nullen)
geteilt. Das Ergebnis wäre dann 123,45678. Das Ergebnis, dass in die
Variable "zahlb" geschrieben wird ist eine 123
************************************************** **********************/
zahlc=(zahl/100000);

//delay (20);

/************************************************** *********************
Beispiel Zahl ist = 12345678
Zur Bestimmung der dritten Ziffer wird nun wieder das Modulo angewendet.

Variable "zahlc" hat den Wert 123. Also passt die 10 in die 123 genau 12
mal hinein und der Rest ist die 3
Also der Wert von "zahlc" ist somit 3.
Das ganze wird Sinngemäß für die anderen 5 stellen der Zahl
durchgeführt, bis alle Ziffern der 8 stelligen Zahl bestimmt wurde.
************************************************** **********************/
zahlc=(zahlc%10);


//Serial.print("Zahl C ="); Serial.println(zahlc);

//delay (200);

// vierte Zahl

zahld=(zahl/10000);

//delay (20);

zahld=(zahld%10);


//Serial.print("Zahl D ="); Serial.println(zahld);

//delay (200);

// fünfte Zahl

zahle=(zahl/1000);

//delay (20);

zahle=(zahle%10);

//Serial.print("Zahl E ="); Serial.println(zahle);

//delay (200);

// sechste Zahl

zahlf=(zahl/100);

//delay (20);

zahlf=(zahlf%10);

//Serial.print("Zahl F ="); Serial.println(zahlf);

//delay (200);

// siebte Zahl

zahlg=(zahl/10);

//delay (20);

zahlg=(zahlg%10);

//Serial.print("Zahl G ="); Serial.println(zahlg);

//delay (200);

// achte Zahl


zahlh=(zahl%10);

//Serial.print("Zahl H ="); Serial.println(zahlh);

//delay (200);

Serial.print("Zahl Neu =");
Serial.print(zahla);
Serial.print(zahlb);
Serial.print(zahlc);
Serial.print(zahld);
Serial.print(zahle);
Serial.print(zahlf);
Serial.print(zahlg);
Serial.println(zahlh);

}

Mcgrizzly123
25.03.2015, 07:30
Pseudo code


for (int i =7; i> 0; i++){

einzelzahl[8-i] = (zahl/10^i);
einzelzahl[8-i] = (einzelzahl[8-i]%10);
//Serial.print ("Zahl "); Serial.print ((8-1)); Serial.print(": "); Serial.println (einzelzahl [8-i]);
}


Oder besser noch die for Schleife andersrum laufen lassen.

Chevy
25.03.2015, 11:01
Hi McGrizzly,

mit Feldern zu arbeiten, hatte ich mir schon gedacht, jedoch bin ich da noch nicht so firm drin. Dein Vorschlag ist schon mal sehr gut. Werde ich gleich mal versuchen umzusetzen.

Für die spätere Ansteuerung meiner Anzeige habe ich mir schon mal ein zwei zweidimensionales Array gebastelt:



byte digi[]={6,7,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36 ,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,} ;
// Digital-Ausgänge deklarieren



byte segx4[]={43,44,45,46,47,48,49,50,51,52,00};
byte segx5[]={33,34,35,36,37,38,39,40,41,42,00};
byte segx6[]={22,23,24,25,26,27,28,29,30,31,32};


byte digits[14][11] = {

{1,1,1,1,1,1,1,0,1,1,0}, // Zahl 0
{1,0,0,0,0,0,0,0,1,1,0}, // Zahl 1
{1,1,1,0,1,1,1,1,1,0,1}, // Zahl 2
{1,1,1,0,1,0,1,1,1,1,1}, // Zahl 3
{1,0,1,1,1,0,0,1,1,1,0}, // Zahl 4
{1,1,1,1,1,0,1,1,0,1,1}, // Zahl 5
{1,1,1,1,1,1,1,1,0,1,1}, // Zahl 6
{1,0,1,0,0,0,1,1,1,1,0}, // Zahl 7
{1,1,1,1,1,1,1,1,1,1,1}, // Zahl 8
{1,1,1,1,1,0,1,1,1,1,1}, // Zahl 9
{1,1,1,1,1,1,1,1,0,0,1}, // Buchstabe E
{1,1,1,1,1,1,0,0,1,1,1}, // Buchstabe U
{1,1,1,1,1,0,1,1,0,1,1}, // Buchstabe S
{1,1,1,1,1,1,1,1,1,1,0}, // Buchstabe A



Wie ich jedoch die ausgewerteten Zahlen der 8 stelligen Eingangszahl mit dem Arrays verbinden weis ich noch nicht. Möglicherweise brauch ich die eingangs gezeigte Funktion garnicht und man kann direkt mit der 8 stelligen Zahl die Anzeige ansteuern. Meine Befürchtung ist, dass ich mich immer mehr in komplizierte Funktionen verstricke und es eigentlich viel einfacher geht.

Gruß Marco

Mcgrizzly123
25.03.2015, 11:31
Hi
habe meinen Betrag editiert da sich ein Fehler eingeschlichen hatte. Ich hoffe das hat nicht zu Verwirrung geführt.;)

Sisor
25.03.2015, 17:59
Ich würde 'byte zahlen[8]' verwenden. Ist zwar 8 Byte groß (64 Bit) [Vergleich: long (32 Bit)], dafür braucht es 0 Rechenpower zur Dekodierung der Zahl und ist übersichtlich.

Chevy
25.03.2015, 18:14
Hi,

den Code von McGrizzly habe ich zwar nicht zum laufen gebracht, aber der Denkanstoss war gut und so habe ich die Funktion etwas komprimieren können.



/*
*
* Copyright (c) 2015 Marco Steinhauser. All rights reserved
*
* Anzeige
* Dieses Test Programm ist für die Anzeige DRAG Race
*
*
* getestet auf Arduino Uno R3
*
*
* Version 1.1
* Erstellt Vers. 1.0 am 24 März 2015
* V. 1.0 Eine 8 stellige Zahl wird in einzelnen Zahlen aufgeteilt
* Zur kontrolle der Funktion wird das Ergebnis auf den
* Seriellen Monitor ausgegeben.
*
* Erstellt Vers. 1.1 bis 1.2 am 25 März 2015
* V. 1.1 Die Funktion der Auswertung wurde mit einer FOR Schleife
* und einem Array Variable realisiert.
* V. 1.2 Die Funktion "error" wurde implementiert. Hier erfolgt
* eine Kontrolle ob die Zahlen in der Array Variable den
* Zahlen aus der Vorgabe entsprechen.

*/

long zahl=34598237; //Beim Durchlauf mit +1 hier 9999999 eintragen.

long errorzahl=0;


long divisor=10000000;

long teilzahl=0;

int i=0;

byte einzelzahl[8];


void setup()
{

Serial.begin(9600);

}

void loop()
{
errorzahl=0;

//zahl = zahl++; //Zahl bei jedem Durchlauf um 1 erhöhen

Serial.println("");
Serial.print("Zahl Vorgabe="); Serial.println(zahl);

delay(2000);
bestimmeZahl();

Serial.print("einzelzahl=");
Serial.print (einzelzahl[0]);
Serial.print (einzelzahl[1]);
Serial.print (einzelzahl[2]);
Serial.print (einzelzahl[3]);
Serial.print (einzelzahl[4]);
Serial.print (einzelzahl[5]);
Serial.print (einzelzahl[6]);
Serial.println (einzelzahl[7]);

error();

if (errorzahl == zahl){
Serial.println("Alles Super!!!!");
}
else {
Serial.println("Fehler!!!!");
}


Serial.print("Error Zahl="); Serial.println(errorzahl);
delay (2000);
}



void bestimmeZahl () // Funktion zum Auswerten einer 8 stelligen Zahl
{


for (int i=0; i<8; i++){
teilzahl=(zahl/divisor);
divisor=(divisor/10);

if (teilzahl >=10) {
teilzahl=(teilzahl%10);
}
einzelzahl[i] = (teilzahl);
}
divisor=10000000;
}

void error()
{

for (int i=0; i<8; i++){
errorzahl = errorzahl*10+einzelzahl[i];
}
}



Habe mal noch eine Funktion eingebunden, die kontrolliert ob die Zahl die in die Array Variable gespeichert wurde, auch der vorgegebenen Zahl entspricht.

Das wird wohl später verwendet, damit die Anzeige keinen Mist anzeigt oder damit eine neue Zahl angefordert werden kann. So oder so ähnlich:-)

Gruß Marco