Thursday, 9 October 2014

Jetson to Arduino over Serial


OK, so this is the plan: every time the temperature of my Jetson TK1 GPU reaches 60C or so, a siren starts howling, a blinding red light is blinking in the dark underground lab and it reflects on screens that output incomprehensible sequences of numbers and data, a robotic voice goes "evacuate the building," "this is an emergency" and other catchy phrases etc, etc..., but first I need to hook up Jetson TK1 to an Arduino board which outputs the temperature to an LCD display... Let's see how this is done...


The connection is materialized through the USB serial port.  We first need to write the Arduino code that simply writes to the LCD screen whatever comes to the Serial port. Note that we have set the BAUD rate to 9600, thus, we need to do the same on Jetson TK1 later.


#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();
}

void loop() {
  char incoming_byte;
  int i = 1;
  while(Serial.available()>0) {
   if (i==1) {
     lcd.setCursor(0, 0);
     lcd.clear();
   }
   incoming_byte = Serial.read();
   lcd.print(incoming_byte);
   lcd.setCursor(i, 0);
   i++;      
  }
  delay(30);
}


You may need to change the line LiquidCrystal lcd(8, 9, 10, 11, 12, 13); depending on how you have connected the LCD screen to your Arduino.  Note that I didn't manage to install the Arduino IDE on Jetson TK1 itself, so I used my laptop to burn (metaphorically speaking) the code on the chip.

Once we're done with this, we connect the Arduino board by USB with Jetson TK1 and we write some simple shell code to send the temperature data across. Here's the code:


#!/bin/bash

usbid=`ls /dev/serial/by-id/ | grep Arduino`
usbid="/dev/serial/by-id/$usbid"
baud_rate=9600;
stty -F $usbid cs8 $baud_rate ignbrk -brkint -icrnl \
  -imaxbel -opost -onlcr -isig -icanon -iexten -echo \
  -echoe -echok -echoctl -echoke noflsh -ixon -crtscts;
tail -f $usbid & bg;
while :
do
temp=`awk '{scaled=$1/1000};END {print scaled}' \
  /sys/devices/virtual/thermal/thermal_zone0/temp`
printf "GPU Temp: %2.1fC" $temp > $usbid
sleep 1;
done


In the beginning it didn't work as expected (it's always like this, isn't it?), but the problem was resolved by adding the line tail -f $usbid & bg;. The caveat is that a connection between the two boards needs to remain active and this is exactly what tail -f does.

1 comment: