
I wanted to create my own live space data feed so I 3D printed an asteroid one of the universities’ new Maker:Bots, based on the drawings here. Hats off to the designer.
The plan was to turn this Asteroid a data feed by connecting a ultrasonic distance meter up to an electric imp to then send an output to COSM. I used the cheap and well documented HC-SR04 and hooked it up to an imp via an ardunio. Ideally I could have gone straight into the imp but because the Imp doesn’t yet have an accurate method of timing built into it’s api, this wasn’t possible.
I found that I was able to get an effective range of up to 4 meters with was perfect.
I initially had a serial connection of out the ardunio into the Imp but because of some very strange formatting issues (plus lack of major documentation on the Squirrel programming language) as well as the slow refresh rate of Imp>COSM (15-25 seconds) I abandoned that idea and went straight for a wired serial ardunio approach.
Modifying the HC-S04 to fit into the Asteriod was tricky, not least because I have to unsolder the transducers and Sugru them back into the model so they would lie almost flush with the surface. Another issue was that any small change to the angle of one of the transducer resulted in total failure, presumably because they were no longer in a position to receive the ultrasonic ping back/reflection. It took some time and patience to get them lined up properly but even then, my effective range has reduced to 3 meters (down from 4)








Code: Ardunio:
/*
HC-SR04 Ping distance sensor]
VCC to arduino 5v GND to arduino GND
Echo to Arduino pin 13 Trig to Arduino pin 12
More info at: http://goo.gl/kJ8Gl
*/
#include <SoftwareSerial.h>
SoftwareSerial impSerial(8, 9); // RX on 8, TX on 9
#define trigPin 12
#define echoPin 13
void setup() {
Serial.begin (19200);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// set the data rate for the SoftwareSerial port
impSerial.begin(19200);
}
void loop() {
int duration, distance;
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
if (distance >= 400 || distance <= 0){
Serial.println(“Out of range”);
}
else {
// Send data from the software serial
if (impSerial.available())
Serial.write(impSerial.read()); // to the hardware serial
// Send data from the hardware serial
if (Serial.available())
impSerial.write(Serial.read()); // to the software serial
}
delay(500);
}
Imp Code:
// Transmit data between UART and Input/OutputPorts on the impee
// by: Jim Lindblom
// SparkFun Electronics
// date: September 26, 2012
// license: BeerWare
// Please use, reuse, and modify this code as you need.
// We hope it saves you some time, or helps you learn something!
// If you find it handy, and we meet some day, you can buy me a beer or iced tea in return.
local rxLEDToggle = 1; // These variables keep track of rx/tx LED toggling status
local txLEDToggle = 1;
// impeeIn will override the InputPort class.
// Whenever data is received to the impee, we’ll jump into the set(c) function defined within
class impeeIn extends InputPort
{
name = “UART Out”;
type = “string”;
// This function takes whatever character was sent to the impee
// and sends it out over the UART5/7. We’ll also toggle the txLed
function set(c)
{
hardware.uart57.write(c);
toggleRxLED();
}
}
local impeeInput = impeeIn(); // assign impeeIn class to the impeeInput
local impeeOutput = OutputPort(“UART In”, “string”); // set impeeOutput as a string
function initUart()
{
hardware.configure(UART_57); // Using UART on pins 5 and 7
hardware.uart57.configure(19200, 8, PARITY_NONE, 1, NO_CTSRTS); // 19200 baud worked well, no parity, 1 stop bit, 8 data bits
}
function initLEDs()
{
// LEDs are on pins 8 and 9 on the imp Shield
// They’re both active low, so writing the pin a 1 will turn the LED off
hardware.pin8.configure(DIGITAL_OUT_OD_PULLUP);
hardware.pin9.configure(DIGITAL_OUT_OD_PULLUP);
hardware.pin8.write(1);
hardware.pin9.write(1);
}
// This function turns an LED on/off quickly on pin 9.
// It first turns the LED on, then calls itself again in 50ms to turn the LED off
function toggleTxLED()
{
txLEDToggle = txLEDToggle?0:1; // toggle the txLEDtoggle variable
if (!txLEDToggle)
{
imp.wakeup(0.05, toggleTxLED.bindenv(this)); // if we’re turning the LED on, set a timer to call this function again (to turn the LED off)
}
hardware.pin9.write(txLEDToggle); // TX LED is on pin 8 (active-low)
}
// This function turns an LED on/off quickly on pin 8.
// It first turns the LED on, then calls itself again in 50ms to turn the LED off
function toggleRxLED()
{
rxLEDToggle = rxLEDToggle?0:1; // toggle the rxLEDtoggle variable
if (!rxLEDToggle)
{
imp.wakeup(0.05, toggleRxLED.bindenv(this)); // if we’re turning the LED on, set a timer to call this function again (to turn the LED off)
}
hardware.pin8.write(rxLEDToggle); // RX LED is on pin 8 (active-low)
}
// This is our UART polling function. We’ll call it once at the beginning of the program,
// then it calls itself every 10us. If there is data in the UART57 buffer, this will read
// as much of it as it can, and send it out of the impee’s outputPort.
function pollUart()
{
imp.wakeup(0.00001, pollUart.bindenv(this)); // schedule the next poll in 10us
local byte = hardware.uart57.read(); // read the UART buffer
// This will return -1 if there is no data to be read.
while (byte != -1) // otherwise, we keep reading until there is no data to be read.
{
server.log(format(“%c”, byte)); // send the character out to the server log. Optional, great for debugging
impeeOutput.set(byte); // send the valid character out the impee’s outputPort
byte = hardware.uart57.read(); // read from the UART buffer again (not sure if it’s a valid character yet)
toggleTxLED(); // Toggle the TX LED
}
}
// This is where our program actually starts! Previous stuff was all function and variable declaration.
// This’ll configure our impee. It’s name is “UartCrossAir”, and it has both an input and output to be connected:
imp.configure(“UartCrossAir”, [impeeInput], [impeeOutput]);
initUart(); // Initialize the UART, called just once
initLEDs(); // Initialize the LEDs, called just once
pollUart(); // start the UART polling, this function continues to call itself
// From here, two main functions are at play:
// 1. We’ll be calling pollUart every 10us. If data is sent from the UART, we’ll send out out of the impee.
// 2. If data is sent into the impee, we’ll jump into the set function in the InputPort.
//
// The end