Probleme mit 'int' to 'const char*'

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