Full Source Code

Version control for project 1 was accomplished by using Git hosted by GitHub.  The repository is openly available at https://github.com/2012SEng466/robots.

Base Station

// Do not remove the include below

#include "arduino/Arduino.h"
#include "radio.h"
#include <avr/interrupt.h>

volatile uint8_t rxflag = 0;

uint8_t station_addr[5] = { 0x66, 0x66, 0x66, 0x66, 0x66 };
uint8_t my_addr[5] = { 0x77, 0x77, 0x77, 0x77, 0x77 };

radiopacket_t packet;

void radio_begin()
{
	pinMode(5, OUTPUT);

	digitalWrite(5, LOW);
	delay(100);
	digitalWrite(5, HIGH);
	delay(100);

	Radio_Init();

	// configure the receive settings for radio pipe 0
	Radio_Configure_Rx(RADIO_PIPE_0, my_addr, ENABLE);
	// configure radio transceiver settings.
	Radio_Configure(RADIO_2MBPS, RADIO_HIGHEST_POWER);

	Radio_Set_Tx_Addr(station_addr);

	delay(1000);
}

void radio_send(char * msg)
{
	int waitedFor = 0;

	packet.type = MESSAGE;
	memcpy(packet.payload.message.address, my_addr, RADIO_ADDRESS_LENGTH);
	packet.payload.message.messageid = 55;
	snprintf((char*)packet.payload.message.messagecontent, sizeof(packet.payload.message.messagecontent), msg);
	Radio_Transmit(&amp;packet, RADIO_WAIT_FOR_TX);

	// wait for retransmit
	while (!rxflag) {
		waitedFor++;
		delay(50);
		if (waitedFor &gt; 10) {
			Serial.println("ERROR: Did not receive ACK.");
			return;
		}
	}

	if (Radio_Receive(&amp;packet) != RADIO_RX_MORE_PACKETS)
	{
		// if there are no more packets on the radio, clear the receive flag;
		// otherwise, we want to handle the next packet on the next loop iteration.
		rxflag = 0;
	}

	// DEBUG
	if (packet.type == ACK)
	{
		digitalWrite(3, !digitalRead(3));
	}
}

int main()
{
	int data;

	sei(); // enable global interrupts, may not be required
	init(); // init arduino

	// enable debug LED pin
	pinMode(3, OUTPUT);
	// enable debug serial
	Serial.begin(9600);

	// wait a little bit, seems to help
	delay(2000);

	// DEBUG
	Serial.println("Program begin");
	digitalWrite(3, LOW);

	// initialize radio settings
	radio_begin();

	for (;;) {
		if (Serial.available())
			data = Serial.read();
		else
			continue;

		data = data - '0';

		switch (data) {
		case 0:
			digitalWrite(3, HIGH);
			radio_send("1");
			break;
		case 1:
			digitalWrite(3, LOW);
			radio_send("2");
			break;
		case 2:
			radio_send("3");
			break;
		case 3:
			radio_send("4");
			break;
		default:
			break;
		}

	}
	return 0;
}

void radio_rxhandler(uint8_t pipe_number)
{
	rxflag = 1;
}

Hover Station

#include <stdio.h>
#include "Servo.h"
#include "arduino/Arduino.h"
#include "radio.h"

#define RADIO_PIN						5
#define MOTOR_PIN						7
#define ECHO_PIN						11
#define TRIG_PIN						12
#define ONBOARD_LED_PIN						13
#define INDICATOR_LED						6

// Polling delay for loop, depending on whether desired height is met
#define POLLING_DELAY_STABLE				1500
#define POLLING_DELAY_FAST				750

#define MOTOR_MIN_OPERATING_SPEED			85
#define MOTOR_MAX_SPEED					175
// motor increments as slowly as possible. This gives us more precision.
#define MOTOR_INCREMENT					1

#define DISTANCE_LOW					1
#define DISTANCE_HIGH					20
// Add this if you want the ball to be considered at desired height when it is off
#define DISTANCE_ERROR_MARGIN				0

// this must be volatile because it's used in an ISR (radio_rxhandler).
volatile uint8_t rxflag = 0;
radiopacket_t packet;
uint8_t station_addr[5] = { 0x66, 0x66, 0x66, 0x66, 0x66 };

Servo motor;
int motor_current_speed = 0; // global var that persistently tracks the motor's speed

// Calibrations for the ball balancing
int desired_distance_current = 8; // Persistently tracks desired distance. Start it somewhere.

// returns distance in inches of sensed object.
int doSonar()
{
	// Sonar setup stuff
	digitalWrite(TRIG_PIN, HIGH);                  // Send a 10uS high to trigger ranging
	delayMicroseconds(10);
	digitalWrite(TRIG_PIN, LOW);

	// Now ping for objects
	int distance = pulseIn(ECHO_PIN, HIGH);        // Read in times pulse
	distance = distance / 148;                     // Calculate distance from time of pulse

	// We aren't worried about sensing very high, so if it's above a certain
	// maximum, for our intents and purposes, ignore it and say there's nothing there
	if (distance &gt;= DISTANCE_HIGH) {
		distance = 0;
	}
	Serial.print("distance: ");
	Serial.println(distance);
	return distance;
}

void motorSetSpeed(int speed)
{
	if (speed &gt; MOTOR_MAX_SPEED)
		speed = MOTOR_MAX_SPEED;
	else if (speed &lt; MOTOR_MIN_OPERATING_SPEED)
		speed = MOTOR_MIN_OPERATING_SPEED;

	motor.write(speed);
	motor_current_speed = speed;

	Serial.print("current motor speed = ");
	Serial.println(motor_current_speed);
}

void motorSpeedUp()
{
	int increment;
	// set increment to 3 depending on speed
	increment = motor_current_speed = (desired_distance - DISTANCE_ERROR_MARGIN) &amp;&amp; distance = DISTANCE_LOW)? tmp : 0;
	desired_distance_current = desired_distance_current + tmp;
}

void setup()
{

	// Default Ardiuno setups
	sei(); // for some premade radio setup that we don't know
	init(); // arduino default init stuff

	delay(2000); // give time to open serial connection
	Serial.begin(9600);

	// Motor
	Serial.println("Attaching...");
	delay(1500);
	motor.attach(MOTOR_PIN);
	motorStop();
	delay(1000);
	motorStartAt(MOTOR_MIN_OPERATING_SPEED);

	// LED!!
	pinMode(ONBOARD_LED_PIN, OUTPUT);
	pinMode(INDICATOR_LED, OUTPUT);
	digitalWrite(INDICATOR_LED, LOW);

	// Radio
	recv_radio_setup();

	// Sonar
	pinMode(ECHO_PIN, INPUT);
	pinMode(TRIG_PIN, OUTPUT);

	Serial.println("Hover station initialized.");
}

int main()
{
	int msgInt, loop_delay;

	setup();

	for (;;) {

		Serial.println("---------------------------------");

		// Get Radio Message
		msgInt = radio_check();

		// If message received, update desired height
		if (msgInt != -1) {
			Serial.print("Received ");
			Serial.println(msgInt);
			setNewDesiredDistance(msgInt);
		}

		// Poll slower when desired height reached
		if (alterMotor(desired_distance_current))
			loop_delay = POLLING_DELAY_FAST;
		else
			loop_delay = POLLING_DELAY_STABLE;

		delay(loop_delay);
	}

	return 0;
}

Python Script for gamepad

'''
basic_control.py
@author: Garrett Owen
@date: January 26, 2012

Based off code from
http://iamtherockstar.com/archive/making-hid-devices-easier-using-pygame-joysticks/
'''

import serial
import pygame
import time
#serialPort = '/dev/tty.usbserial-A7004Jg4' # Arduino Mega
serialPort = '/dev/tty.usbmodemfd121'       # Arduino Uno
baudRate = 9600

# Open Serial Connection to Arduino Board
ser = serial.Serial(serialPort, baudRate, timeout=1);

'''
Gets joystick data and prints it
'''
pygame.init()
j = pygame.joystick.Joystick(0)
j.init()
print 'Initialized Joystick : %s' % j.get_name()

# Keeps a history of buttons pressed so that one press does
# not send multiple presses to the Arduino Board
button_history = [0,0,0,0,0,0,0,0,0,0,0,0]

try:
    while True:
        pygame.event.pump()

#        # Used to read input from the two joysticks
#        for i in range(0, j.get_numaxes()):
#            if j.get_axis(i) != 0.00:
#                print 'Axis %i reads %.2f' % (i, j.get_axis(i))
#
#        time.sleep(1)

        for i in range(0, j.get_numbuttons()):
            if j.get_button(i) != 0:
                if not button_history[i]:
                    print 'Button %i reads %i' % (i, j.get_button(i))
                    button_history[i] = 1
                    ser.write(str(i))
            else:
                button_history[i] = 0

except KeyboardInterrupt:
    j.quit()

7 thoughts on “Full Source Code

  1. I’ve been trying to build a quadcopter on my own as a side project to my schooling and you’re site has been an extremely reliable and useful source to me. Thank you. Although, I have encountered one thing that I am very curious about in your code. You continually use the phrases “>” and “<” with no reference to them anywhere in the code. Would you mind explaining what they are? Also, did you prefer using the mystery or the turnegy ESC, code wise, and if so, do you have to use the servo commands (milli vs deg) respectively?
    Thanks a ton!

    ~Alex

      • Hey Alex,

        Sorry about that! WordPress seems to escape all my < and > signs. If you see a &gt it should be a > and if you see a &lt it should be a <

    • learn Unity3d software its very easy if you are planning to use it only for app development (and not game development) and also planning to use it only with arduino.

  2. Pingback: 2015、都铎王朝の「導入」と都铎ゴース腕時計シリーズとブルーバージョンと新しい携帯電話。今年の大ニュースから都铎王朝でバーゼル2015内部機械運動の紹介。は都铎はロレックスに属し

Comments are closed.