Hallo,
ich versuche gerade, zwei Skripte zu kombinieren und hab ein Programmiersprachen-Problem, da ich C nicht kann.
Hier ist der Code mit den entscheidenden Stellen:
#include <Wire.h>
#include <VirtualWire.h>
#include <Serial.h>
#include <Ultrasonic.h>
int tank = 1500;//Ölstand bei "voll" in mm
int oelstand;
Ultrasonic ultrasonic(trigpin,echopin);
void setup() {
…
}
void loop(){
…
int cmdistance;
oelstand = tank - cmdistance;
vw_send((uint8_t *)oelstand, strlen(oelstand)); // Zeile 44
…
}
Folgende Fehler treten auf:
_433TX3:44: error: invalid conversion from 'int' to 'const char*'
_433TX3:44: error: initializing argument 1 of 'size_t strlen(const char*)'
ich hab schon gesucht und nichts gefunden bzw. nichts verstanden.
Wer weiss, wies geht?
Danke
Gunther
Mit einem Integer kannst du selbstverständlich nicht strlen() machen. Das ist totaler Blödsinn. Und man kann auch nicht ein Zahl auf einen Pointer Casten, sondern nur Adressen.
Du brauchst für Integer nach C String und umgekehrt Konvertierungs-Funktionen:
http://www.cplusplus.com/reference/cstdlib/itoa/
itoa = integer to array. Array weil Strings in C lediglich Null-terminierte char Arrays sind
String nach Integer geht mit atoi():
http://www.cplusplus.com/reference/cstdlib/atoi/
Bist du aber sicher dass du hier wirklich Strings senden willst? Man kann hier auch einfach ein Byte Array nehmen. Dazu musst du lediglich die Adresse des Integers Casten. Statt die Zahl selbst:
vw_send((uint8_t *)&oelstand, sizeof(oelstand));
Das schickt die zwei Bytes, so wie sie sind in binäar. Nicht als String.
Hallo Serenifly,
Danke für die schnelle Antwort. Ich hab die geänderte Zeile eingefügt.
Nun scheint keine Probleme mehr zu geben. Jetzt kann ich mal testen!
Danke Gunther
Hallo,
das Senden funktioniert jetzt, allerdings die Auswertung beim Empfang nicht.
Hier soll ausgewertet werden:
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
Ist das auch der falsche Befehl für meine Datenart?
Im SeriellMonitor kommt zumindest ein "Neue Zeile" Befehl an, sonst nichts.
Hier der ganze Code des Empfängers:
#include <Wire.h>
#include <VirtualWire.h>
#include <Serial.h>
void setup()
{
vw_set_ptt_inverted(true); // Required for DR3100
vw_set_rx_pin(12);
vw_setup(4000); // Bits per sec
pinMode(13, OUTPUT);
Serial.begin(38400); // open Serial Monitor to PC
vw_rx_start(); // Start the receiver PLL running
Serial.println("Receiving...");
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
digitalWrite(13,1); // turn on led
if(buflen == 1) { // if just one character per time
if(buf[0]==13)
Serial.println(""); // newline
else
Serial.print(char(buf[0]));
}
else
for(int n=0;n<buflen;n++) {
if(buf[n]==13)
Serial.println(""); // newline
else
Serial.print(char(buf[n]));
Serial.println(""); // insert newline at end of buffer
}
digitalWrite(13,0); // turn off led
}
}
Vielen Dank für Hilfe
Gunther
Ok, dann willst du wohl doch Strings. Dann wie gesagt itoa():
http://www.cplusplus.com/reference/cstdlib/itoa/
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#gaa571de9e773dde59b0550a5ca4bd2f00
char buffer[10];
itoa(zahl, buffer, 10);
Wandelt zahl in einen C String im Dezimalsystem um und schreibt das Ergebnis in buffer. Der Rückgabe-Wert ist der Puffer, also kann man die Funktion direkt in andere Funktionen einsetzten.
Hallo Serenifly,
nochmal Danke für die schnelle Hilfe. Ich hab versucht den Code einzufügen. Ist aber echt mehr Fischen im Trüben. Hier mal der ganze Sendeloop mit Deiner Erweiterung:
void loop(){
digitalWrite(dcpin, HIGH);
delay(500);
int cmdistance;
long microsec = ultrasonic.timing();
cmdistance = ultrasonic.CalcDistance(microsec,Ultrasonic::CM);//Ergebnis in Millimeter
oelstand = tank - cmdistance;
char buffer[10];
itoa(oelstand, buffer, 10);
vw_send((uint8_t *)oelstand, sizeof(oelstand));
//vw_send((uint8_t *)msg, strlen(msg)); für cont char
vw_wait_tx(); // Wait until the whole message is gone
delay(200); // wait a little while before the next character
digitalWrite(dcpin, LOW);
delay(2000);
}
Am Empfänger kommen inzwischen einzelne, eher kryptische Buchstaben an.
vw_send((uint8_t *)oelstand, sizeof(oelstand));
Du solltest natürlich das Puffer Array verschicken
Eventuell musst du auch den Null-Terminator mitschicken. Also strlen(buffer) + 1 machen.
Ich danke Dir schon mal für deine Geduld. Inzwischen werden die Daten gesendet. Auf der Auswertungsseite haperte noch. Da weiß ich nicht, wie ich die Daten behandeln soll.
Ankommen müssten Werte zwischen 10 und 1500. Im Moment kommen Zahlenreihen an.
Der Loop auf der Auswertungsseite (ich hab jetzt eine andere Vorlage benutzt), der noch nicht richtig funktioniert:
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
int i;
digitalWrite(13, true); // Flash a light to show received good message
// Message with a good checksum received, dump it.
Serial.print("Got: ");
for (i = 0; i < buflen; i++)
{
Serial.print(buf[i], HEX);
Serial.print(" ");
}
Serial.println("");
digitalWrite(13, false);
}
}
Der Abschnitt im Sendeskript sieht jetzt so aus:
char buffer[10];
itoa(oelstand, buffer, 10);
strlen(buffer) + 1;
vw_send((uint8_t *)buffer, sizeof(buffer));
Ausgegeben im SM wird sowas (hatte ich noch vergessen):
Got: 310 303 0 320 0 0 2000 0 0 3110
Got: 303 311 0 320 0 0 2000 0 0 3110
Got: 301 303 321 311 0 0 2000 0 0 3110
Got: 302 311 0 311 0 0 2000 0 0 3110
Got: 301 303 321 321 0 0 2000 0 0 3110
Du solltest unbedingt mal etwas C Grundlagen lernen anstatt wild Code abzutippen. Wenn dann so
vw_send((uint8_t *)buffer, strlen(buffer) + 1);
Das +1 ist aber wohl doch nicht nötig:
http://www.airspayce.com/mikem/arduino/VirtualWire/transmitter_8pde-example.html
Schadet aber auch nichts
Beschreibe lieber mal was du mit dem empfangenen String machen willst. Das ist sinnvoller als in fremdem Code herumzupfuschen der vielleicht für was ganz anderes gedacht ist und hundert mal komplizierter aussieht als er wahrscheinlich sein müsste.
Ich habe selber gefunden und hab diese Zeile:
Serial.print(buf[i], HEX);
verändert in:
Serial.print(char(buf[i]));
Ich empfange jetzt meine Entfernungsdaten, allerdings mit einem unschönen Sonderzeichen am Schluß.
Got: 1365�(�Â
Wie kann man das loswerden? Edit: Hat sich erledigt. Die Zeichen sind jetzt weg.
Noch eine Sache geht nicht. Der Sensor müsste mir auch negative Werte ausgeben, da ich ja 150 cm - $wert rechnen lasse. Das macht das Skript aber nicht. Wenns in diesen Bereich geht, dann wird's unsinnig.
Der nächste Schritt ist es, die Daten, die ich alle zwei oder drei Stunden abfrage, zu sammeln und darzustellen. Das will ich über hem lösen. Das läuft bei mir auf dem Raspi. Ein neues Modul dafür gibts auch.
Das sollte doch auch gehen, oder nicht? Wieso so einen Aufwand und jedes Zeichen einzeln verarbeiten?
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen))
{
Serial.println((char*)buf);
}
}
Wenn der String korrekt terminiert ist (was der Fall sein sollte wenn man den Terminator durch das +1 bei der Länge mitschickt), sollte das nur den eigentlichen String anzeigen. In der Theorie zumindest.
Das mit dem iterieren über jedes Zeichen ist eher Testcode als eine praktische Anwendung.
Hallo Serenifly,
und vielen Dank für die Hilfe. Muss jetzt aufhören!
Gunther