Tutorial - Google Docs and the Arduino Yún

Next in my series of Arduino Yún tutorials is a guide on how to send your own data from the Yún to a Google Docs spreadsheet. This builds on the original example by showing how to send data from the analogue and digital inputs, as well as from a real-time clock connected via I2C.

http://tronixstuff.com/2013/11/11/tutorial-google-docs-arduino-yun/

Cool! Nice tutorial.

bitfrosting:
Cool! Nice tutorial.

Thank you. Will do another one next week.

Any recommendations on how to tweak this to log to the sd card and then periodically send a batch of data to google docs? I'm thinking this saves on transmission energy, maybe? Maybe not actually...because it is always on. Hmm.

I still wish I had an easy way to power down the atheros board when I'm not using it. I'm Considering an external module to power the Yun (the whole thing) up every x minutes and power it down after receiving a confirmation (eg pin high). Seems silly but I have no continuous power.

Anyway. Sorry about the rant. I think I will use a stream to open a data file and upload the whole file as strings by line and then when successful, I'll start logging to a new file. I'll store the name if that file in yun's memory so I know which one to upload each time. Or perhaps it is better to enumerate the file name so the code will just look for the file with the highest number and upload that one. Hmm.

In any event, thanks for the tut. Bring us a long way towards a micro datalogger and transmitter.

Temboo charges you money for running their little bit of code. Is there any way to append a spreadsheet in google docs without Temboo?

You can try this: PushingBox - Notifications for your Internet of Things devices

Here you can read about methodology:
a) Google Product Forums
b) http://translate.google.pl/translate?sl=ro&tl=en&js=n&prev=_t&hl=pl&ie=UTF-8&u=http%3A%2F%2Fwww.jola.ro%2Fproiecte%2Findex.php%2Fethernet%2Farduino-si-google-docs&act=url

Append a spreadsheet in google docs without Temboo

Google Spreadsheets Python API

opkg update
opkg install nano
opkg install python-openssl
opkg install python-expat
opkg install distribute
easy_install gspread

Go to Google Drive and create an empty spreadsheet you will use for testing.
and get spreadsheet id https://docs.google.com/spreadsheet/ccc?key=0Ao9lSur2AThldE1uQk1MVGtWS25vRTBuTXM4NWpGRFE&usp=drive_web#gid=0

nano /mnt/sda1/googledoc.py
#!/usr/bin/python
import gspread

# Login with your Google account
gc = gspread.login('abc@gmail.com', 'googlepassword')
sh = gc.open_by_key('0Ao9lSur2AThldE1uQk1MVGtWS25vRTBuTXM4NWpGRFE')
wks= sh.get_worksheet(0)
wks.update_acell('B2', "it's down there somewhere, let me take another look.")
chmod 755  /mnt/sda1/googledoc.py
/mnt/sda1/googledoc.py

Confirm spreadsheet from Google drive is updated

Thanks guys. I'm currently sending data to xively.com, but will try what you've shown here.

Thanks, those instructions worked perfectly.

Almost perfectly. It works fine when I run the python code from a console. When I try to run the python code from a Process, the data doesn’t show up in the spreadsheet. Instead of numbers, it shows “NONE” in the cells. Here’s the Arduino code:

// This sketch sends temperature and humidity data to the Linux side of an Arduino Yun.

#include <Process.h>
#include <DHT.h>
#include <FileIO.h>

#define LEDpin 13
#define DHTTYPE DHT22 // DHT 22  (AM2302 wired temperature and humidity sensor)
#define DHTPIN 7  // The DHT output is connected to digital pin 7.
DHT dht(DHTPIN, DHTTYPE); //define the DHT object

// set up net client info:
const unsigned long postingInterval = 60000;  //delay between updates
unsigned long lastRequest = 0;      // when you last made a request
String logString;

void setup() {
  Bridge.begin();
  FileSystem.begin();

  pinMode(DHTPIN, INPUT);
  pinMode(LEDpin, OUTPUT);
  
  dht.begin();    // Start reading from the AM2302 temperature and humidity sensor
  
  // disable wifi for this sketch
  Process wifiDisable;
  wifiDisable.runShellCommand("wifi down");
  Process wifiCheck;
  wifiCheck.runShellCommand("/usr/bin/pretty-wifi-info.lua");
  String msgString;
  while (wifiCheck.available() > 0) {
    char c = wifiCheck.read();
    msgString += c;
  }
  File logFile = FileSystem.open("/mnt/sda1/arduino/log.txt", FILE_APPEND);
  logFile.println(getTimeStamp());
  logFile.println(msgString);
  logFile.close();
  
  Process startPython;
  startPython.runShellCommand("python /mnt/sda1/DHTbridgetest.py");
    
  // Do a first update immediately
  updateData();
  lastRequest = millis();
}

void loop() {
  // get a timestamp so you can calculate reading and sending intervals:
  long now = millis();

  // if the sending interval has passed since your
  // last connection, then connect again and send data:
  if (now - lastRequest >= postingInterval) {
    updateData();
    lastRequest = now;
  }
}

void updateData() {
  
  // read sensor values
  float dhtTemperature = dht.readTemperature();
  float dhtHumidity = dht.readHumidity();
  String timestamp = getTimeStamp();
  
  // send data to Linux processor
  Bridge.put("timestamp", timestamp);
  Bridge.put("temperature", String(dhtTemperature));
  Bridge.put("humidity", String(dhtHumidity));

  logString = String(dhtTemperature);
  logString += ", ";
  logString += dhtHumidity;
  
  File dataFile = FileSystem.open("/mnt/sda1/arduino/dhtdata.txt", FILE_APPEND);
  dataFile.print(timestamp);
  dataFile.print(", ");
  dataFile.println(logString);
  dataFile.close();

}

// This function returns a string with the time stamp
String getTimeStamp() {
  String result;
  Process time;
  // date is a command line utility to get the date and the time
  // in different formats depending on the additional parameters
  time.begin("date");
  time.addParameter("+%d/%m/%y %T");  // parameters: +%d/%m/%y for the complete date dd/mm/yy
  //             T for the time hh:mm:ss
  time.run();  // run the command

  // read the output of the command
  while (time.available() > 0) {
    char c = time.read();
    if (c != '\n')
      result += c;
  }

  return result;
}

Here’s the python code:

#!/usr/bin/python

import gspread
import time
import sys    
sys.path.insert(0, '/usr/lib/python2.7/bridge/') 
                                                
from bridgeclient import BridgeClient as bridgeclient

value = bridgeclient()

# Login with your Google account
gc = gspread.login('address@gmail.com', 'password')
sh = gc.open_by_key('spreadsheet key here')
wks= sh.get_worksheet(0)

try:
	while True:
		# read data from Arduino side of the Yun
		timestamp = value.get('timestamp')
		temperature = value.get('temperature')
		humidity = value.get('humidity')

		# print formatted data to console
    		print("{0:20}{1:12}{2:12}".format("Time","Temperature","Humidity"))
		print("{0:20}{1:12}{2:12}".format(timestamp,temperature,humidity))
		print

		# send data to Google Drive spreadsheet
		wks.append_row([timestamp, temperature, humidity])
		
		time.sleep(60)

except KeyboardInterrupt:
	print("\ndone")
startPython.runShellCommand("python /mnt/sda1/DHTbridgetest.py");
// Do a first update immediately
updateData();

DHTbridgetest.py finished before updateData() even start.

import time

...
timestamp =0
		while  timestamp != 0:
			timestamp = value.get('timestamp')
			temperature = value.get('temperature')
			humidity = value.get('humidity')
			time.sleep(1)

add loop to wait data from ATmega32u4 at Python.

Thanks. I tried this and it didn't work though. I think that the while loop will never get executed because timestamp will always equal zero ("timestamp = value.get('timestamp')" will never execute, so the value of timestamp won't change).

What did work though, is that I put a line in the rc.local file to get the python script to start on boot of Linino:

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

python /mnt/sda1/DHTbridgetest.py

wifi-live-or-reset
exit 0

Thanks for your help. I wouldn't have gotten this to work without it.

import time
...
timestamp =0
		while  True:
			timestamp = value.get('timestamp')
			temperature = value.get('temperature')
			humidity = value.get('humidity')
			time.sleep(1)
			if timestamp != 0:
            			break

Thanks. I did something similar to that. Also, if anyone else is watching this thread, another way to keep a python script running after you've started it in a console window is to add a "&" to the end of the command to get the script to run in the background:

python /mnt/sda1/pythoncode.py&
timestamp = 0
temperature = 0
humidity = 0

try:
	while True:
		# read data from Arduino side of the Yun
		timestamp = value.get('timestamp')
		temperature = value.get('temperature')
		humidity = value.get('humidity')

		if timestamp != 0:
			# print formatted data to console
    			#print("{0:20}{1:12}{2:12}".format("Time","Temperature","Humidity"))
			#print("{0:20}{1:12}{2:12}".format(timestamp,temperature,humidity))
			#print
	
			#write data to a file
			file=open('/mnt/sda1/pythondata.txt','a')
			line= "{0:20}{1:12}{2:12}".format(timestamp,temperature,humidity)
			print >>file, line

			# send data to Google Drive spreadsheet
			wks.append_row([timestamp, temperature, humidity])

			# set values to zero until the next time
			# the arduino populates them
			value.put('timestamp',0)
			value.put('temperature',0)
			value.put('humidity',0)
					
		time.sleep(5)

except KeyboardInterrupt:

How do you get Wire and Bridge library to work together? :slight_smile:

Check my post here:
http://forum.arduino.cc/index.php?topic=218328.0

One thing you could try is to #include <Console.h> and use Console.print instead of Serial.print. I have not had a sketch work on the Yun where I used the Serial library. Then again, I only connect to the Yun via ethernet and haven’t tried using USB.