Go Down

Topic: Referenz zum Senden von mehrziffrigen Zahlen via Serial (Read 1 time) previous topic - next topic

bluebubble

Liebes Forum

Nun habe ich schon 4h damit verbracht das Forum nach Keywords zu diesem Thema zu durchforsten und bin langsam am verzweifelt. :~

Das Szenario:

Der Servo, welcher um 180 Grad schwenken kann, soll mit der Konsole angesteuert werden. Bis jetzt habe ich das auch fertig gebracht, mit dem Resultat, das ich nur von 0 bis 9 Grad schwenken konnte. Ich möchte ihn jedoch auch bis 179 mit der Konsole ansteuern können, jedoch nimmt er immer nur die erste Ziffer und vernachlässigt die folgen.

Nun frage ich, ob mir jemand mit einem Link zu einem wahrscheinlich schon bestehenden Thread weiterhelfen könnte.

Vielen Dank

mfg

bluebubble

sth77

Zeig doch erst mal deinen bisherigenn Code, daran lässt sich das besser erklären, wo der Fehlerteufel eventuell lauert.
Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

uwefed

#2
Dec 05, 2011, 04:03 pm Last Edit: Dec 05, 2011, 05:39 pm by uwefed Reason: 1
Ich verstehe das so daß Du mehrere Byte ashii Werte der Zahlen auf der seriellen Schnittselle bekommst und diese zu einer Zahl zusammenfügen mußt.

Code: [Select]
int incomingByte;  
char Data[8];
int i;
unsigned long Tempo;

void setup()
{
 Serial.begin(9600);
}

void loop(){
  do {
    if (Serial.available()) {      
      Data[i] = Serial.read();
      i++;
      }    
    if(i<1)Tempo = millis();
    } while (i<5&&(millis()-Tempo) < 500);
 
  Data[i] = 0;    
  incomingByte = atoi(Data);  
  i=0;
  Serial.println(incomingByte);
}

Yeahuno

Quote
long incomingByte; 
char eingabe;
char Data[8];
int i;
unsigned long Tempo;


void setup()
{
Serial.begin(9600);
pinMode(11, OUTPUT);   
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
}


void loop()
{
  do {
            if (Serial.available())
            {
            Data = Serial.read();
            eingabe = Data;
            i++;
            }   
                  if(i<1)
                  Tempo = millis();
                  {
                  }
}
    while
    (i<7&&(millis()-Tempo) < 500); 
    Data = 0;   
    incomingByte = atof(Data); 
    i=0;
    Serial.print(incomingByte);
   
                 if (eingabe == '+')
                 {
                 digitalWrite(10, LOW);    //
                 digitalWrite(9, HIGH);    //
                 analogWrite(11, incomingByte);   //
                 Serial.println("LINKS");
                 }
                 if (eingabe == '-')
                 {
                 digitalWrite(10, HIGH);    //
                 digitalWrite(9, LOW);    // 250
                 analogWrite(11, incomingByte);   //
                 Serial.println("RECHTS");
                 }
                 if (eingabe == ',')
                 {
                 analogWrite(11, 200);   //
                 delay(100);
                 analogWrite(11, 150);   //
                 delay(100);
                 analogWrite(11, 0);   //
                 Serial.println("STOP");
                 }
}



das war für eine H-Brücke gedacht.

die Eingabe +255 über die Konsole hat das PWM Signal auf 255 gesetzt. (+- = rechts links)

kannst du dir ja entsprechend umbauen, die ganze letzte If Schleife raus und incomingbyte auf die Servo Position setzten.

Gruß

bluebubble

Hallo

Vielen vielen Dank für eure die schnelle Hilfe.

Der Code von uwefed sieht ziemlich Verständlich aus, jedoch komme ich bei 2 Zeilen nich ganz draus:

Code: [Select]

if(i<1)Tempo = millis();
     } while (i<5&&(millis()-Tempo) < 500);


Könntest du mir vielleicht noch erläutern was deren Bedeutung ist?

Danke nochmals

mfg

bluebubble

uwefed

#5
Dec 05, 2011, 05:32 pm Last Edit: Dec 05, 2011, 05:37 pm by uwefed Reason: 1
Code: [Select]
if(i<1)Tempo = millis();
Speichert bei jedem Durchgang die Zeit. Dies solange bis erste Byte kommt, dann nicht mehr.

Code: [Select]
} while (i<5&&(millis()-Tempo) < 500);
Wartet bis 5 Zeichen gekommen sind oder 0,5 Sekunden. Dies ist wichtig, wenn Du eine manuelle Eingabe im Terminal hast und der Benutzer für zehn 10 schreibt und nicht 00010 (alle 5 Stellen). Bei einer Übertragung von einem programm aus kannst Du das mit den führenden Nullen machen. Ein Mensch macht das nicht. Diese Kode ist unabhängig von der Anzahl der übermittelten Zeichen.

Yeahuno hat den Kode in seine Anwendung eingebaut.
Zu Umwandlung String-Zahl kann atoi (array to int) oder atof (array to float) verwendet werden.

Grüße Uwe

bluebubble

#6
Dec 06, 2011, 10:49 am Last Edit: Dec 06, 2011, 01:26 pm by bluebubble Reason: 1
Danke für den Hinweis.
Ich bin zur Zeit leider nicht zuhause und kann deshalb denn Code nicht anwenden. Aus Verständnisgründen habe ich mal diesen Code kurz geschriben der die Anwendung mit dem Servo ausführen sollte. Könnte mir jemand sagen ob er funktionieren würde, oder wo sich ein Fehler eingeschlichen hat?

Code: [Select]

include.servo.h*
Servo derServ;
int i;
char data[3];
unsigned long zeit;
int wert;
{
 Serial.bergin(9600);
 derServ.attach(3);
}
void loop()
{
 if (Serial.available());
   {
     data[i] = Serial.read();
     i++;
     if (i>1) zeit = millis();
     if (i>3 ||(millis() - zeit) > 500)
     {
       wert = atoi(data);
       if (wert>179)wert =179;
       else if (wert<0) wert = 0;
       derServ.write(wert);
       i = 0;
      }
     }
}

uwefed

Das Array
Code: [Select]
char data[3]; muß 4 groß sein da nach den Ziffern eine "NULL" stehen muß damit atoi funktioniert. Die NULL wird bei string als "Endsignal" eingefügt.

Vor
Code: [Select]
wert = atoi(data);
fehlt das
Code: [Select]
data[i] = 0;

Du brauchst die "do while" Schleife damit das dann im Programm funktioniert. Dein Kode funktioniet ieleicht auch ohne do while aber sobald der Kode umfangreicher wird ist es aus.

Bitte kopiere einfach meinen Kode schamlos ohne ihn nachbauen zu wollen. ;) ;) ;)

Grüße Uwe

bluebubble

ok

Ist vielleicht offtopic, aber die do/while Schlaufe interessiert mich grad. Ich hatte vor kurzem ein kleines Projekt, bei dem eine RGB-Led gleichzeit die verschiedenen Farbwerte faden. D.h.bei Pin 3 soll der Wert von 180 auf 255 mit einem delay(15) faden, gleichzeitig soll Pin 5 von 255 auf 40 mit delay(30) faden. Mit meinen jetztigen code-Kenntnissen bin ich zum schluss gekommen, das dadurch 3 Arduinos erforderliche währen um dieses Resultat zu erziele, da mit den Ddelays ja die einzelnen Schritte nicht gleichzeitig ablaufen könnten. Könnte mit jemand einen kleinen Dankanstoss liefern? :smiley-red: :smiley-red:

MueThoS

Ja kann ich:
http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

Kein delay verwenden!
Die Millies immer beobachten und wenn genug zeit vergangen ist deinen wert anpassen.
Aktuelles Millies als neues altes millies speichern und wieder mit millies + delay vergleichen

bluebubble

#10
Dec 06, 2011, 05:18 pm Last Edit: Dec 06, 2011, 05:52 pm by bluebubble Reason: 1
OH biensur!

Vielen Dank dir. Könnte mir jemand kurz den Kindergartencode reviewen?

Code: [Select]

#define rot = 3;
#define gruen = 5;
#define blau = 6;

int rLeuchte = 0;
int gLeuchte = 0;
int bLeuchte = 0;

int rStatus = 0;
int gStatus = 0;
int bStatus = 0;

#define rInterv = 30;
#define gInterv = 18;
#define bInterv = 20;

unsinged long millisjetzt = 0;
unsinged long millisletzt = 0;

boolean rGut = false;
boolean gGut = false;
boolean bGut = false;

void setup()
{
  pinMode(rot, OUTPUT);
  pinMode(gruen, OUTPUT);
  pinMode(blau, OUTPUT);
}

void loop()
{
  if (rGut == false)rLeuchte =random(255);
  if (gGut == false)gLeuchte =random(255);
  if (bGut == false)bLeuchte =random(255);

  millijetzt = millis()
  if ((millisjetzt - millisletzt) > rInterv)
  {
    if (rLeuchte > rStatus) rStatus++;
    else if (rLeuchte < rStatus) rStatus--;

    if (rLeuchte != rStatus) rGut = true;
    else if (rLeuchte == rStatus) rGut = false;
   }

if ((millisjetzt - millisletzt) > gInterv)
  {
    if (gLeuchte > gStatus) gStatus++;
    else if (gLeuchte < gStatus) gStatus--;

    if (gLeuchte != gStatus) gGut = true;
    else if (gLeuchte == gStatus) gGut = false;
   }

  if ((millisjetzt - millisletzt) > bInterv)
  {
    if (bLeuchte > bStatus) bStatus++;
    else if (bLeuchte < bStatus) bStatus--;

    if (bleuchte != bStatus) bGut = true;
    else if (bLeuchte == bStatus) bGut = false;
   }
  millisletzt = millisjetzt;
}


mfg

bluebubble


Yeahuno


stellst du jetzt code rein den du nicht selber testest ?

Quote
millijetzt = millis()


da fehlt ein s

bluebubble

Danke

Zur Zeit habe ich hab erst am Wochenende ein Arduino zur Hand. Ich wollte vor allem wissen ob der Code denn ich geschribe habe nicht zu umständlich ist, und sobald der Code grösser ist abkackt.

Danke nochmals

mfg

bluebuble

Go Up