Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
| ||||||
|
This was my first arduino robot car project. I want to get better at building robots and eventually start building larger more advanced versions of my own. Eventually, I want to use this robot as a good proof of concept model in showing how feasible it can be to create many cheap robots to use for emergency situations (natural disaster, police scouts, etc).
Update 3/26/17:Update 5/14/17: It's a work in progress but I've mounted a Walabot Pro! It's amazing as it can give:
- High 3D resolution
- 18 antenna array
- Imaging API
- Raw signal data
If you want to know where to buy these awesome sensors, go to: https://walabot.com/
Go to https://walabot.com/getting-started to download their SDK for windows, linux, or raspberry pi (In my case, I had trouble getting set up with my raspberry pi 2).
After you've downloaded their SDK, go ahead and check out their starter project to set up your environment: https://github.com/Walabot-Projects/Walabot-HelloWalabot.
Big tip, when they tell you to insert this line:
pip install WalabotAPI --no-index --find-links="%PROGRAMFILES%\Walabot\WalabotSDK\python\\"
into your CMD (assuming you're using windows), you may get an error. I spent a while before I figured out the problem. Firstly as a precautionary measure, I redownloaded python 3.7 https://www.python.org/downloads/ and was still confused as to why I couldn't verify my python version via CMD. I found out the command to initiate the python ide environment was actually
py
instead of
python
so keep that in mind. From there I used command:
py -m pip install WalabotAPI --no-index --find-links="%PROGRAMFILES%\Walabot\WalabotSDK\python\\"
to download the necessary libraries. From there you can go ahead and download their sample projects to run from CMD using the "py" command.
Note: You can use http://api.walabot.com/index.html to get started on projects but I really prefer https://github.com/Walabot-Projects instead.
My main challenge right now is trying to bridge my arduino code for my robot to the python code for the Walabot. I've looked at forums and found from others that it's unlikely I'd be able to run python on an arduino. I'll have to move over to programming this in C++ or C# to combine my robot functions with the Walabot data.
I'm looking to get a sensor map running where the robot will navigate through a room and pinpoint every single object. I'd have more hypersonic sensors on board to record objects 360 degrees. I'd essentially have a sensor map with multiple points plotted on a graph to give myself a 2D visual representation of the room from a ground level.
Walabot
Pythonfrom __future__
import print_function, division
from math
import sin, cos, radians
import WalabotAPI
try: #for Python 2
import Tkinter as tk
except ImportError: #for Python 3
import tkinter as tk
try: #for Python 2
range = xrange
except NameError:
pass
class GUI(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title('Walabot SeeThroughDemo')# window title
self.option_add("*Font", "TkFixedFont")# default monospace font
self.mainFrame = MainFrame(self)# init window conponents
self.mainFrame.pack()
class Walabot:
def __init__(self):
self.wlbt = WalabotAPI
self.WalabotError = self.wlbt.WalabotError
self.wlbt.Init()
self.wlbt.SetSettingsFolder()
def Connect(self):
self.wlbt.ConnectAny()
self.isConnected = True
self.wlbt.SetProfile(self.wlbt.PROF_SHORT_RANGE_IMAGING)
self.wlbt.SetDynamicImageFilter(self.wlbt.FILTER_TYPE_NONE)
self.wlbt.SetArenaX(-4, 4, 0.8)
self.wlbt.SetArenaY(-6, 4, 0.8)
self.wlbt.SetArenaZ(3, 8, 0.5)
self.wlbt.SetThreshold(50)
self.wlbt.Start()
except self.wlbt.WalabotError as err:
if err.code != 19: #'WALABOT_INSTRUMENT_NOT_FOUND'
raise err
def Calibrate(self):
self.wlbt.StartCalibration()
while self.wlbt.GetStatus()[0] == self.wlbt.STATUS_CALIBRATING:
self.wlbt.Trigger()
def isTargets(self):
self.wlbt.Trigger()
return True
if self.wlbt.GetImagingTargets()
else False
def stopAndDisconnect(self):
self.wlbt.Stop()
self.wlbt.Disconnect()
def print_targets(targets):
system("cls"
if platform == "win32"
else "clear")# clear the screen
if not targets:
print("No targets")
return
d_min = min(targets, key = lambda t: t[2])[2]# closest target
d_amp = max(targets, key = lambda t: t[3])[2]#
"strongest"
target
if d_min == d_amp:
print("THE DISTANCE IS {:3.0f}\n".format(d_min))
else :
print("CALCULATING...\n")
def main():
wlbt = Walabot()
wlbt.connect()
if not wlbt.isConnected:
print("Not Connected")
else :
print("Connected")
wlbt.start()
while True:
print_targets(wlbt.get_targets())
class MainFrame(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.statusPanel = StatusPanel(self)
self.ctrlPanel = ControlPanel(self)
self.statusPanel.pack()
self.ctrlPanel.pack(expand = True, fill = "both")
def initLoop(self):
try:
self.ctrlPanel.connLabel.config(text = "CONNECTING")
wlbt.Connect()
self.ctrlPanel.connLabel.config(text = "CALIBRATING")
wlbt.Calibrate()
self.ctrlPanel.connLabel.config(text = "CONNECTED")
self.loopId = self.after_idle(self.loop)
except wlbt.WalabotError:
self.stopLoop()
def loop(self):
try:
if wlbt.isTargets():
self.statusPanel.statusLabel.config(
text = "Treasure Found!", bg = "gold"
)
else :
self.statusPanel.statusLabel.config(
text = "Scanning", bg = "snow1"
)
self.loopId = self.after_idle(self.loop)
except wlbt.WalabotError:
self.stopLoop()
def stopLoop(self):
wlbt.stopAndDisconnect()
self.statusPanel.statusLabel.config(text = "")
self.ctrlPanel.connLabel.config(text = "DISCONNECTED")
self.after_cancel(self.loopId)
class StatusPanel(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.statusLabel = tk.Label(self, width = 30, height = 5, bg = "snow1")
self.statusLabel.pack()
class ControlPanel(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.strtBtn = tk.Button(
self, text = "Start", width = 6, command = self.master.initLoop
)
self.stopBtn = tk.Button(
self, text = "Stop", width = 6, command = self.master.stopLoop
)
self.connLabel = tk.Label(self, text = "DISCONNECTED")
self.strtBtn.pack(side = "left")
self.stopBtn.pack(side = "left")
self.connLabel.pack(side = "right")
if __name__ == '__main__':
wlbt = Walabot()
guiApp = GUI()
guiApp.mainloop()
Remote Monitoring with Azure
JavaScript// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
'use strict';
// Azure IoT packages
var Protocol = require('azure-iot-device-http').Http;
var Client = require('azure-iot-device').Client;
var ConnectionString = require('azure-iot-device').ConnectionString;
var Message = require('azure-iot-device').Message;
var keypress = require('keypress');
var five = require("johnny-five"),
board, motor, led;
var BLESerialPort = require('ble-serial').SerialPort;
var bleSerial = new BLESerialPort();
var board = new five.Board({port: bleSerial, repl: false});
var hostName = '<IOTHUB_HOST_NAME>';
var deviceId = '<DEVICE_ID>';
var sharedAccessKey = '<SHARED_ACCESS_KEY>';
// String containing Hostname, Device Id & Device Key in the following formats:
// "HostName=<iothub_host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"
var connectionString = 'HostName=' + hostName + ';DeviceId=' + deviceId + ';SharedAccessKey=' + sharedAccessKey;
// Sensor data
var temperature = 0;
var humidity = 0;
var externalTemperature = 0;
// Create IoT Hub client
var client = Client.fromConnectionString(connectionString, Protocol);
// Helper function to print results for an operation
function printErrorFor(op) {
return function printError(err) {
if (err) console.log(op + ' error: ' + err.toString());
};
}
// Send device meta data
var deviceMetaData = {
'ObjectType': 'DeviceInfo',
'IsSimulatedDevice': 0,
'Version': '1.0',
'DeviceProperties': {
'DeviceID': deviceId,
'HubEnabledState': 1,
'CreatedTime': '2015-09-21T20:28:55.5448990Z',
'DeviceState': 'normal',
'UpdatedTime': null,
'Manufacturer': 'Intel',
'ModelNumber': 'Edison',
'SerialNumber': '12345678',
'FirmwareVersion': '159',
'Platform': 'node.js',
'Processor': 'Intel',
'InstalledRAM': '64 MB',
'Latitude': 47.617025,
'Longitude': -122.191285
},
'Commands': [{
'Name': 'SetTemperature',
'Parameters': [{
'Name': 'Temperature',
'Type': 'double'
}]
},
{
'Name': 'SetHumidity',
'Parameters': [{
'Name': 'Humidity',
'Type': 'double'
}]
}]
};
board.on("ready", function() {
var temp = new five.Temperature({
pin: "A0",
controller: "GROVE"
});
// --------------CONTROL.JS PART --------------------
//load atafruit motor shield configs
var configs = five.Motor.SHIELD_CONFIGS.ADAFRUIT_V2;
//create each motor
var motor1 = new five.Motor(configs.M1);
var motor2 = new five.Motor(configs.M2);
var motor3 = new five.Motor(configs.M3);
var motor4 = new five.Motor(configs.M4);
//set high level drive functions
function forward(speed){
motor1.reverse(speed);
motor2.forward(speed);
motor3.forward(speed);
motor4.reverse(speed);
}
function reverse(speed){
motor1.forward(speed);
motor2.reverse(speed);
motor3.reverse(speed);
motor4.forward(speed);
}
function left(speed){
motor1.forward(speed);
motor2.forward(speed);
motor3.forward(speed);
motor4.forward(speed);
}
function right(speed){
motor1.reverse(speed);
motor2.reverse(speed);
motor3.reverse(speed);
motor4.reverse(speed);
}
function stop(){
motor1.stop();
motor2.stop();
motor3.stop();
motor4.stop();
}
// make `process.stdin` begin emitting "keypress" events
keypress(process.stdin);
// listen for the "keypress" event
process.stdin.on('keypress', function (ch, key) {
console.log('got "keypress"', key);
//make it so you can close the process with ctrl-c...
if (key && key.ctrl && key.name == 'c') {
process.exit();
}
if (key && key.name == 'w') {
forward(255);
console.log('forward command');
}
if (key && key.name == 's') {
reverse(255);
console.log('reverse command');
}
if (key && key.name == 'a') {
left(255);
console.log('left command');
}
if (key && key.name == 'd') {
right(255);
console.log('right command');
}
if (key && key.name == 'q') {
stop();
console.log('stop');
}
});
process.stdin.setRawMode(true);
// ------------------- End Control.js ----------------------
client.open(function (err, result) {
if (err) {
printErrorFor('open')(err);
} else {
console.log('Sending device metadata:\n' + JSON.stringify(deviceMetaData));
client.sendEvent(new Message(JSON.stringify(deviceMetaData)), printErrorFor('send metadata'));
client.on('message', function (msg) {
console.log('receive data: ' + msg.getData());
try {
var command = JSON.parse(msg.getData());
switch (command.Name) {
case 'SetTemperature':
temperature = command.Parameters.Temperature;
console.log('New temperature set to :' + temperature + 'F');
client.complete(msg, printErrorFor('complete'));
break;
case 'SetHumidity':
humidity = command.Parameters.Humidity;
console.log('New humidity set to :' + humidity + '%');
client.complete(msg, printErrorFor('complete'));
break;
default:
console.error('Unknown command: ' + command.Name);
client.reject(msg, printErrorFor('complete'));
break;
}
}
catch (err) {
printErrorFor('parse received message')(err);
client.reject(msg, printErrorFor('reject'));
}
});
// start event data send routing
var sendInterval = setInterval(function () {
temperature = temp.celsius;
var data = JSON.stringify({
'DeviceID': deviceId,
'Temperature': temperature,
'Humidity': humidity,
'ExternalTemperature': externalTemperature
});
console.log('Sending device event data:\n' + data);
client.sendEvent(new Message(data), printErrorFor('send event'));
}, 1000);
client.on('error', function (err) {
printErrorFor('client')(err);
if (sendInterval) clearInterval(sendInterval);
client.close();
});
}
});
});
{
"name": "azure-samples-node-edison-rm",
"version": "0.0.1",
"private": true,
"description": "Remote monitoring sample demonstrating how to use the Azure IoT device SDK for Node.js on the Intel Edison",
"author": "Microsoft Corp.",
"license": "MIT",
"dependencies": {
"azure-iot-common": "1.0.2",
"azure-iot-device": "1.0.2",
"azure-iot-device-amqp": "1.0.2",
"azure-iot-device-http": "1.0.2",
"azure-iot-device-mqtt": "1.0.2",
"edison-io": "^0.9.4",
"johnny-five": "^0.9.33"
},
"devDependencies": {
"jshint": "^2.8.0"
},
"scripts": {
"lint": "jshint --show-non-errors .",
"test": "npm -s run lint"
}
}
Old Arduino code for obstacle avoidance
Arduino#include <Servo.h> //servo library
Servo myservo; // create servo object to control servo
int Echo = A4;
int Trig = A5;
int in1 = 6;
int in2 = 7;
int in3 = 8;
int in4 = 9;
int ENA = 5;
int ENB = 10;
int ABS = 110;
int rightDistance = 0,leftDistance = 0,middleDistance = 0 ;
void _mForward()
{
analogWrite(ENA,ABS);
analogWrite(ENB,ABS);
digitalWrite(in1,LOW);
digitalWrite(in2,HIGH);
digitalWrite(in3,LOW);
digitalWrite(in4,HIGH);
Serial.println("go forward!");
}
void _mBack()
{
analogWrite(ENA,ABS);
analogWrite(ENB,ABS);
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
digitalWrite(in3,HIGH);
digitalWrite(in4,LOW);
Serial.println("go back!");
}
void _mleft()
{
analogWrite(ENA,ABS);
analogWrite(ENB,ABS);
digitalWrite(in1,LOW);
digitalWrite(in2,HIGH);
digitalWrite(in3,HIGH);
digitalWrite(in4,LOW);
Serial.println("go left!");
}
void _mright()
{
analogWrite(ENA,ABS);
analogWrite(ENB,ABS);
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
digitalWrite(in3,LOW);
digitalWrite(in4,HIGH);
Serial.println("go right!");
}
void _mStop()
{
digitalWrite(ENA,LOW);
digitalWrite(ENB,LOW);
Serial.println("Stop!");
}
/*Ultrasonic distance measurement Sub function*/
int Distance_test()
{
digitalWrite(Trig, LOW);
delayMicroseconds(2);
digitalWrite(Trig, HIGH);
delayMicroseconds(20);
digitalWrite(Trig, LOW);
float Fdistance = pulseIn(Echo, HIGH);
Fdistance= Fdistance/58;
return (int)Fdistance;
}
void setup()
{
myservo.attach(3);// attach servo on pin 3 to servo object
Serial.begin(9600);
pinMode(Echo, INPUT);
pinMode(Trig, OUTPUT);
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT);
pinMode(in4,OUTPUT);
pinMode(ENA,OUTPUT);
pinMode(ENB,OUTPUT);
_mStop();
}
void loop()
{
myservo.write(90);//setservo position according to scaled value
delay(500);
middleDistance = Distance_test();
#ifdef send
Serial.print("middleDistance=");
Serial.println(middleDistance);
#endif
if(middleDistance<=20)
{
_mStop();
delay(500);
myservo.write(5);
delay(1000);
rightDistance = Distance_test();
#ifdef send
Serial.print("rightDistance=");
Serial.println(rightDistance);
#endif
delay(500);
myservo.write(90);
delay(1000);
myservo.write(180);
delay(1000);
leftDistance = Distance_test();
#ifdef send
Serial.print("leftDistance=");
Serial.println(leftDistance);
#endif
delay(500);
myservo.write(90);
delay(1000);
if(rightDistance>leftDistance)
{
_mright();
delay(180);
}
else if(rightDistance<leftDistance)
{
_mleft();
delay(180);
}
else if((rightDistance<=20)||(leftDistance<=20))
{
_mBack();
delay(180);
}
else
{
_mForward();
}
}
else
_mForward();
}
int LED=13;
volatile int state = LOW;
char getstr;
int in1=6;
int in2=7;
int in3=8;
int in4=9;
int ENA=5;
int ENB=10;
int ABS=135;
void _mForward()
{
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
digitalWrite(in3,HIGH);
digitalWrite(in4,LOW);
Serial.println("go back!");
}
void _mBack()
{
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(in1,LOW);
digitalWrite(in2,HIGH);
digitalWrite(in3,LOW);
digitalWrite(in4,HIGH);
Serial.println("go forward!");
}
void _mleft()
{
analogWrite(ENA,ABS);
analogWrite(ENB,ABS);
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
digitalWrite(in3,LOW);
digitalWrite(in4,HIGH);
Serial.println("go left!");
}
void _mright()
{
analogWrite(ENA,ABS);
analogWrite(ENB,ABS);
digitalWrite(in1,LOW);
digitalWrite(in2,HIGH);
digitalWrite(in3,HIGH);
digitalWrite(in4,LOW);
Serial.println("go right!");
}
void _mStop()
{
digitalWrite(ENA,LOW);
digitalWrite(ENB,LOW);
Serial.println("Stop!");
}
void stateChange()
{
state = !state;
digitalWrite(LED, state);
}
void setup()
{
pinMode(LED, OUTPUT);
Serial.begin(9600);
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT);
pinMode(in4,OUTPUT);
pinMode(ENA,OUTPUT);
pinMode(ENB,OUTPUT);
_mStop();
}
void loop()
{
getstr=Serial.read();
if(getstr=='f')
{
_mForward();
}
else if(getstr=='b')
{
_mBack();
delay(200);
}
else if(getstr=='l')
{
_mleft();
delay(200);
}
else if(getstr=='r')
{
_mright();
delay(200);
}
else if(getstr=='s')
{
_mStop();
}
else if(getstr=='A')
{
stateChange();
}
}
Comments