I decided to check if it is possible to post a sensor data to xively.com (ex cosm.com ex pachube.com) using bash only without building a complicated system like the one I attempted to build here: My first attempt to build a home monitoring/control system. And, in fact, it turned out to be quite simple.
We are going to need an Arduino with a temperature sensor that is able to answer to a string request with a float number representing sensor value. In my case, Arduino is programmed to send temperature in degrees Celsius if it receives a string "Get" over UART. So, what we need to do is to write a bash script that sends the string "Get" to a comport, recieves data and posts it to xively.com.
We are going to use /dev/ttyUSB0 comport (you may have a different one, so check this first), so let's declare a variable:
Now we can send data to the comport by just doing echo
And read data back by just doing read
Here may be a few problems. Like speed of the port is not matching the speed of Arduino. Or the number of data or stop bits not matching. Or pretty much anything else not matching, so we have to make sure that the comport operates with the same parameters Arduino does. So before sending and receiving data to and from the comport, set its parameters:
I was at this point able to communicate with Arduino, but I still had a problem of the Arduino resetting every time I echo to it. I was not able to overcome this problem, although it seems simple. Options like -hup (or -hupcl) and clocal have to solve the problem of DTR going down every time. But they don't. So what I do, is:
So now I have the data from the sensor as a string and I just need to send this data to xively.com. I simply do that with cURL:
where $DATA_STRING is the data in json format:
Here I had another problem when putting the variable directly into the string. Arduino sends "\r\n" as the end of the line when you use Serial.println(). And that '\r' totally corrupts the line. But we need the '\n' to detect the end of data. To get rid of '\r', you can use stty option igncr. So, the full script now looks as:
So now save your script (I save it as ~/bin/xively), make it executable (chmod +x ~/bin/xively) and add it to the scheduler to execute regularly by typing crontab -e and adding the following line to your crontab:
And now your sensor data is in the cloud! Check this out: https://xively.com/feeds/337476649
We are going to need an Arduino with a temperature sensor that is able to answer to a string request with a float number representing sensor value. In my case, Arduino is programmed to send temperature in degrees Celsius if it receives a string "Get" over UART. So, what we need to do is to write a bash script that sends the string "Get" to a comport, recieves data and posts it to xively.com.
We are going to use /dev/ttyUSB0 comport (you may have a different one, so check this first), so let's declare a variable:
SERIAL_DEVICE=/dev/ttyUSB0
Now we can send data to the comport by just doing echo
echo "Get" > $SERIAL_DEVICE
And read data back by just doing read
read TEMP < $SERIAL_DEVICE
Here may be a few problems. Like speed of the port is not matching the speed of Arduino. Or the number of data or stop bits not matching. Or pretty much anything else not matching, so we have to make sure that the comport operates with the same parameters Arduino does. So before sending and receiving data to and from the comport, set its parameters:
stty -F $SERIAL_DEVICE cs8 9600 clocal -crtscts -cstopb -parenb -hup -ixany \ igncr -ixoff -ixon -isig iexten >/dev/null
I was at this point able to communicate with Arduino, but I still had a problem of the Arduino resetting every time I echo to it. I was not able to overcome this problem, although it seems simple. Options like -hup (or -hupcl) and clocal have to solve the problem of DTR going down every time. But they don't. So what I do, is:
- I open the port:
exec 3<>$SERIAL_DEVICE
- I wait for 3 seconds whil Arduino reboots:
sleep 3
- I do my echo and read
- And I close the comport:
exec 3>&-
So now I have the data from the sensor as a string and I just need to send this data to xively.com. I simply do that with cURL:
curl -ssss \ --request PUT \ --header "X-ApiKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ --data "$DATA_STRING" \ https://api.xively.com/v2/feeds/XXXXXXXXX > /dev/null
where $DATA_STRING is the data in json format:
DATA_STRING='{"version":"1.0.0", "datastreams":[{"id":"TC", "current_value":"'"$TEMP"'"}]}'
Here I had another problem when putting the variable directly into the string. Arduino sends "\r\n" as the end of the line when you use Serial.println(). And that '\r' totally corrupts the line. But we need the '\n' to detect the end of data. To get rid of '\r', you can use stty option igncr. So, the full script now looks as:
#!/bin/bash #serial SERIAL_DEVICE=/dev/ttyUSB0 #port setting stty -F $SERIAL_DEVICE cs8 9600 clocal -crtscts -cstopb -parenb -hup -ixany \ igncr -ixoff -ixon -isig iexten >/dev/null sleep 0.1 exec 3<>$SERIAL_DEVICE sleep 3 echo "Get" > $SERIAL_DEVICE read TEMP < $SERIAL_DEVICE DATA_STRING='{"version":"1.0.0", "datastreams":[{"id":"TC", "current_value":"'"$TEMP"'"}]}' #echo "$DATA_STRING" exec 3>&- curl -ssss \ --request PUT \ --header "X-ApiKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ --data "$DATA_STRING" \ https://api.xively.com/v2/feeds/XXXXXXXXXX > /dev/null
So now save your script (I save it as ~/bin/xively), make it executable (chmod +x ~/bin/xively) and add it to the scheduler to execute regularly by typing crontab -e and adding the following line to your crontab:
*/2 * * * * ~/bin/xively
And now your sensor data is in the cloud! Check this out: https://xively.com/feeds/337476649
No comments:
Post a Comment