Passing a string to a (void) function

So I am having trouble getting my head round the fact you can't pass a string to a function. And despite reading many posts about it I still don't understand how to do it. =(

The goal is to have a SendData function which accepts a string like e=935 and calls a PHP page to save the data in a MySQL database (the PHP bit is working fine).

The script is a hacking together of various ideas... :astonished: The code runs on my Arduino Mega 2560 with official Ethernet sheild.

At the moment the code:

  • Reads current meter readings which are generated every 6 seconds by my CurrentCost connected to RX1 and tries to report that with the SendData function
  • Checks if the state of digital input DryerPin has changed and if so tries to report that with the SendData function

Here are the relevant (I think) lines of code and I attach the full script so you can see the context.

char StrToSend[20];
strcpy (StrToSend, "e=" + power);
SendData(StrToSend);
void SendData (char *ToSend) {

	// Idea from http://arduino.cc/en/Tutorial/WebClient
	if (client.connect()) {
		Serial.println("Connected");
		// Make a HTTP request:
		client.print("GET /~maidhous/dev/input/in.php?");
		client.print(ToSend);
		Serial.println(ToSend);
		client.print("&p=");
		client.print(DataWritePassword); // Password
		client.println(" HTTP/1.0");
		client.println();
	}
	
	// if there are incoming bytes available 
	// from the server, read them and print them:
	if (client.available()) {
		//Serial.println("Server responded");
		//char c = client.read();
		//Serial.print(c);
	}
	
	// if the server's disconnected, stop the client:
	//if (!client.connected()) {
	//Serial.println();
	//Serial.println("Disconnecting.");
	delay(30);
	client.stop();
}

In my SendData function the Serial.println(ToSend); line prints just "1". I am expecting it to print something like "e=935".

How can I call my SendData function with different instructions each time, or is there a better way entirely?

Thank you :slight_smile:

Full script:

/*

Home Automation script 03

CurrentCost power logging inspiration:
http://web.archive.org/web/20100724220142/http://e.inste.in/2008/06/16/interfacing-the-currentcost-meter-to-an-arduino/
*/

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  0x90, 0xA2, 0xDA, 0x00, 0x7A, 0x56 };
byte ip[] = { 192,168,1,177 };
byte gateway[] = { 192, 168, 1, 254 };
byte server[] = { 1,1,1,1 }; // IP to call to save data
String DataWritePassword = "xxx";

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
Client client(server, 80);

// Local variables
// char wattsStr[5];
// int watts = 0;
// int previousWatts = 0;

// Set up pins
int sensorPin = A0;    // select the input pin for the outside light sensor
int ledPin = 8;      // select the pin for the tell-tale LED
int sensorValue = 0;  // variable to store the value coming from the outside light sensor
int DryerPin = 30; // Digital in for dryer on/off digital sensor

// Set up CurrentCost variables
char startPattern[] = "<ch1><watts>"; // The start of the pattern to look for
char endPattern[] = "<"; // The end of the pattern to look for
int pos = 0; // Position of search
byte readByte = 0xFF; // Initial setting for CurrentCost serial in
int state = 0; // Tracks state of serial in from CurrentCost
int power = 0;

int FlashTimes; // For flashing the LED

// Set up dryer sensor
int DryerState = 0; // dryer off initially
int OldDryerState = 0; // Previous dryer state

char StrToSend[20];

void setup()  {
	// Define pin modes for tx and rx pins:
	//  pinMode(rxPin, INPUT);
	//  pinMode(txPin, OUTPUT);
	// Set the data rate for the SoftwareSerial port
	//  softSerial.begin(9650);

	// Set the data rate for the hardware serial port
	Serial.begin(9600); // Diagnostic serial port
	Serial1.begin(57600); // Pin 19 = RX1 on the Arduino Mega 2560 connects to CurrentCost

	// start the Ethernet connection:
	Ethernet.begin(mac, ip, gateway);

	// declare the ledPin as an OUTPUT:
	pinMode(ledPin, OUTPUT);

	pinMode(DryerPin, INPUT);           // set pin to input
	digitalWrite(DryerPin, HIGH);       // turn on pullup resistors

	// give the Ethernet shield a second to initialize:
	delay(1000);
}

void loop()
{
	readByte = Serial1.read();
	if (readByte == 0xFF) {
		//digitalWrite(ledPin, LOW);
	}
	else
	{
		//Serial.print(readByte, BYTE);
		gotByte();
		//digitalWrite(ledPin, HIGH);
	}

	DryerState = digitalRead(DryerPin);
	// Serial.println(DryerState);
	if (DryerState != OldDryerState) { // Send the change of state
		strcpy (StrToSend, "d=" + DryerState);
		SendData(StrToSend);
		OldDryerState = DryerState;
	}
}

void gotByte() { // Interpret the serial data coming in from the CurrentCost
	if (state == 0) { // Check for starting pattern in the data
		if (readByte == startPattern[pos]) {
			++pos;
			if (startPattern[pos] == 0) { // Finished matching start pattern
				++state;
				power = 0;
			}
		}
		else
		{
			pos = 0;
		}
	}
	else if (state == 1) { // Start reading power
		if (readByte == endPattern[0]) {
			int i = 0;
			// finished reading power
			// light up lights

			// while (wattLevels[i] < power) {
			//digitalWrite(wattPins[i], HIGH);
			//++i;
			//}

			// and clear remaining
			//while (i < 5) {
			//digitalWrite(wattPins[i], LOW);
			//++i;
			//}

			state = 0;
			Serial.println(power);

			// read the value from the sensor:
			sensorValue = analogRead(sensorPin);
			
			// Call SendData
			strcpy (StrToSend, "e=" + power);
			SendData(StrToSend);
      
			// Flash the LED once for each 500W
			// See this for the 0.5 bit: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1260132933
			FlashTimes = (int) ((power / 500) + 0.5);
			Serial.println(FlashTimes);
			if (FlashTimes == 0) { // Make it flash at least once
				FlashTimes = 1;
			}
			for (int x = 0; x <= FlashTimes; x++) { // Changed < to <=
				digitalWrite(ledPin, HIGH);
				delay(100);
				digitalWrite(ledPin, LOW);
				delay(100);
			}



		}
		else
		{
			// read another digit
			power = power * 10 + readByte - '0';
		}
	}

}

void SendData (char *ToSend) {

	// Idea from http://arduino.cc/en/Tutorial/WebClient
	if (client.connect()) {
		Serial.println("Connected");
		// Make a HTTP request:
		client.print("GET /~maidhous/dev/input/in.php?");
		client.print(ToSend);
		Serial.println(ToSend);
		client.print("&p=");
		client.print(DataWritePassword); // Password
		client.println(" HTTP/1.0");
		client.println();
	}
	
	// if there are incoming bytes available 
	// from the server, read them and print them:
	if (client.available()) {
		//Serial.println("Server responded");
		//char c = client.read();
		//Serial.print(c);
	}
	
	// if the server's disconnected, stop the client:
	//if (!client.connected()) {
	//Serial.println();
	//Serial.println("Disconnecting.");
	delay(30);
	client.stop();
}

Why are you trying to pass the string? The only string you are ever passing to it is global.

maidbloke:

strcpy (StrToSend, "e=" + power);

SendData(StrToSend);

You don't say what power is but I'm going to assume it's an integer of some sort.

In my opinion if the string syntax is constant and only the value changes, it would make more sense to pass the integer number into your output function, and do the formatting inside your function. However, the code to do the formatting would be the same either way. You can't append a number to a 'C' string just by using the + operator. There are various ways you could do it, but one very flexible approach is to use sprintf() to format your string:

sprintf(StrToSend, "e=%d", power);
// StrToSend now contains "e=xxx" where xxx is the decimal representation of [b]power[/b].

Sprintf() is a standard 'C' runtime library function which is widely documented and I'm sure that Google will turn up millions of tutorials and examples of using it. It's also documented in the AVR Libc section of the Arduino reference.

So I am having trouble getting my head round the fact you can't pass a string to a function.

Probably because you CAN.

strcpy (StrToSend, "e=" + power);

Grab your calculator. What is "e=" plus the value in power? The + operator is NOT a concatenation operator, no matter how desperately you want it to be one.