Mark Easley
Published

Teaching Mechatronics with MSP430 LaunchPad Racerbot

The MSP430 Racerbot design is an easy way to integrate mechatronics into an academic course or workshop using off the shelf components.

IntermediateProtip1.5 hours3,257
Teaching Mechatronics with MSP430 LaunchPad Racerbot

Things used in this project

Story

Read more

Schematics

ASEE_2016_TI_LaunchPad_Mechatronics_HD.pdf

ASEE_2016_TI_LaunchPad_Mechatronics_HD.pptx

Code

MSP430Racerbot.ino

Arduino
/* MSP430Racerbot.ino
 *
 * MSP430 LaunchPad + Grove I2C Mini Motor Driver v1.0 + CC110L BoosterPack
 * 
 * The recommended robot chassis to use is the Adafruit Mini Robot Rover or
 * Magician Chassis
 *
 * The default I2C address of the Grove Mini I2C Motor Driver v1.0 is 0xC4
 * and 0xC0. To work with the LaunchPad we need to perform a bitwise right
 * shift of one bit (ex. 0xC0 >> 1) which will make the new addresses used
 * in this program 0x60 and 0x62
 */

/**
 *  WirelessTest - test transceiver sketch using AIR430Boost FCC driver.
 *  Copyright (C) 2012-2013 Anaren Microwave, Inc.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 * 
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 * 
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  This example demonstrates usage of the AIR430BoostETSI library which uses
 *  the 430Boost-CC110L AIR Module BoosterPack created by Anaren Microwave, Inc.
 *  and available through the TI eStore, for the European Union.
 *
 *  ----------------------------------------------------------------------------
 *
 *  Note: This file is part of AIR430Boost.
 *
 *  ----------------------------------------------------------------------------
 *
 *  Description
 *  ===========
 *
 *  Each radio will send a message consisting of: 1 byte counter, 5 byte static 
 *  text. The counter will count from 0 to 9 and will rollover. Each radio will 
 *  wait in receive mode for approximately one second. Upon receiving data, or 
 *  timeout of one second, the radio receive function will return. If valid data 
 *  was received, the radio's receiverOn() method will return the number of bytes
 *  that were received. In this example, the data can be monitored on the serial 
 *  port (please refer to printTxData() and printRxData() functions).
 *
 *  ----------------------------------------------------------------------------
 * 
 *  This example assumes that two BoosterPacks will be used to showcase the 
 *  wireless radio communication functionality. This same code should be 
 *  programmed to both LaunchPad development kits.
 *
 *  This BoosterPack relies on the SPI hardware peripheral and two additional 
 *  GPIO lines for SPI chip-select and GDO0 for packet handling. They use pins 18 
 *  and 19 respectively. 
 *
 *  In the default configuration, this BoosterPack is not compatible with an 
 *  external crystal oscillator. This can be changed, if necessary, and would
 *  require reconfiguration of the BoosterPack hardware and changes to the 
 *  AIR430BoostFCC library. Refer to the BoosterPack User's Manual if necessary.
 *
 *  For complete information, please refer to the BoosterPack User's Manual available at:
 *  https://www.anaren.com/air/cc110l-air-module-boosterpack-embedded-antenna-module-anaren
 *  
 *  To purchase the 430Boost-CC110L AIR module BoosterPack kit, please visit the TI eStore at:
 *  https://estore.ti.com/430BOOST-CC110L-CC110L-RF-Module-BoosterPack-P2734.aspx
 */

// The AIR430BoostFCC library uses the SPI library internally. Energia does not
// copy the library to the output folder unless it is referenced here.
// The order of includes is also important due to this fact.
#include <SPI.h>
#include <AIR430BoostFCC.h>
#include <Wire.h>
#include "SparkFunMiniMoto.h"  // Include the MiniMoto library
// -----------------------------------------------------------------------------
/**
 *  Global data
 */

// Data to write to radio TX FIFO (60 bytes MAX.)
unsigned char txData[6] = { 'S', 'A', 'i', 'r', '!', '\0' };    

// Data to read from radio RX FIFO (60 bytes MAX.)
unsigned char rxData[6] = { 'S', 'S', 'S', '\0', '\0', '\0' };

// Create two MiniMoto instances, with different address settings.
MiniMoto motor0(0xC4 >> 1); // A1 = 1, A0 = clear CH1
MiniMoto motor1(0xC0 >> 1); // A1 = 1, A0 = 1 (default) CH2

int duty = 0;

// -----------------------------------------------------------------------------
// Debug print functions

void printTxData()
{
  Serial.print("TX (DATA): ");
  Serial.println((char*)txData); 
}

void printRxData()
{
  /**
   *  The following illustrates various information that can be obtained when
   *  receiving a message. This includes: the received data and associated 
   *  status information (RSSI, LQI, and CRC_OK bit).
   */
  Serial.print("RX (DATA, RSSI, LQI, CRCBIT): ");
  Serial.print("(");
  Serial.print((char*)rxData);
  Serial.print(", ");
  Serial.print(Radio.getRssi());
  Serial.print(", ");
  Serial.print(Radio.getLqi());
  Serial.print(", ");
  Serial.print(Radio.getCrcBit());
  Serial.println(")");
}

// -----------------------------------------------------------------------------
// Main example

void setup()
{
  // The radio library uses the SPI library internally, this call initializes
  // SPI/CSn and GDO0 lines. Also setup initial address, channel, and TX power.
  Radio.begin(0x01, CHANNEL_4, POWER_MAX);

  // Setup serial for debug printing.
  Serial.begin(9600);
  // join i2c bus (address optional for master)
  Wire.begin(); 

  Serial.println("Robot is listening...");
  /**
   *  Setup LED for example demonstration purposes.
   *
   *  Note: Set radio first to ensure that GDO2 line isn't being driven by the 
   *  MCU as it is an output from the radio.
   */
   
  pinMode(RED_LED, OUTPUT);     // initialize the RGB LED
  pinMode(GREEN_LED, OUTPUT);   // initialize the RGB LED
  digitalWrite(RED_LED, LOW);   // set the LED off
  digitalWrite(GREEN_LED, LOW); // set the LED off
}

void loop()
{
  
  digitalWrite(GREEN_LED, HIGH);
  delay(20);
  digitalWrite(GREEN_LED, LOW);

  
  // Turn on the receiver and listen for incoming data. Timeout after 1 seconds.
  // The receiverOn() method returns the number of bytes copied to rxData.
  if (Radio.receiverOn(rxData, sizeof(rxData), 1000) > 0)
  {
    /**
     *  Data has been received and has been copied to the rxData buffer provided
     *  to the receiverOn() method. At this point, rxData is available. See
     *  printRxData() for more information.
     */
    digitalWrite(RED_LED, HIGH);
    printRxData();                  // RX debug information
    if(rxData[0] == 'F'){
      Serial.println("Forward!");
      if(rxData[1] == 'S'){
        motor0.MotoDrive(20);
        motor1.MotoDrive(20);
      }
      else if(rxData[1] == 'F') {
        motor0.MotoDrive(100);
        motor1.MotoDrive(100);
      }
      //driveMotor(0x60); // left wheel HIGH
      //driveMotor(0x62); // right wheel HIGH
    }
    else if(rxData[0] == 'L'){
      Serial.println("Left Turn!");
      if(rxData[1] == 'S'){
        motor0.MotoDrive(20);
        motor1.MotoStop();
      }
      else if(rxData[1] == 'F'){
        motor0.MotoDrive(100);
        motor1.MotoStop();
      }
      //stopMotor(0x60);  // left wheels LOW
      //driveMotor(0x62);  // right wheels HIGH
    }
    else if(rxData[0] == 'R'){
      Serial.println("Right Turn!");
      if(rxData[1] == 'S'){
        motor0.MotoStop();
        motor1.MotoDrive(20);
      }
      else if(rxData[1] == 'F'){
        motor0.MotoStop();
        motor1.MotoDrive(100);
      }
      //driveMotor(0x60);  // left wheels HIGH
      //stopMotor(0x62);   // right wheels LOW
    }
    else if(rxData[0] == 'B'){
      Serial.println("Reverse!");
      if(rxData[1] == 'S'){
        motor0.MotoDrive(-20);
        motor1.MotoDrive(-20);
      }
      else if(rxData[1] == 'F'){
        motor0.MotoDrive(-100);
        motor1.MotoDrive(-100);
      }
    }
    else{
      Serial.println("Stop!");
      motor0.MotoStop();
      motor1.MotoStop();
      //stopMotor(0x60);  // left wheels LOW
      //stopMotor(0x62);   // right wheels LOW
    }
  }
  digitalWrite(RED_LED, LOW);
}

//This function will drive the DRV8830 motor driver
//found on 
void driveMotor(byte addr)
{
  Serial.println("begin drive tx");
  Wire.beginTransmission(addr); // transmit to device at device i2c address
  Serial.println("address");
  Wire.write(0x01);             // sends first bit
  Wire.write(0x80);             // sends one byte  
  Serial.println("before stop");
  Wire.endTransmission(addr);       // transmit to device at device i2c address
  Serial.println("end of transmission");
  Wire.beginTransmission(addr); // stop transmitting
  Wire.write(0x00);             // sends first bit
  Wire.write(0xFE);             // sends one byte 
  Wire.endTransmission(addr);       // stop transmitting
  Serial.println("end of transmission");
  delay(100);
}

// Stop the motor by providing a heavy load on it.
void brakeMotor(byte addr)
{
  Serial.println("begin brake tx");
  Wire.beginTransmission(addr); // transmit to device at device i2c address
  Wire.write(0x00);             // sends first bit
  Wire.write(0x03);             // sends one byte  
  Wire.endTransmission();       // stop transmitting
  Serial.println("end of transmission");
  delay(100); 
}

// Coast to a stop by hi-z'ing the drivers.
void stopMotor(byte addr)
{
  Serial.println("begin stop tx");
  Wire.beginTransmission(addr); // transmit to device at device i2c address
  Wire.write(0x01);             // sends first bit
  Wire.write(0x00);             // sends one byte  
  Wire.endTransmission();       // stop transmitting
  Serial.println("end of transmission");
  delay(100); 
}

SparkFunMiniMoto.h

Arduino
/****************************************************************
Example code demonstrating the use of the Arduino Library for
the SparkFun MiniMoto board, which uses the TI DRV8830 IC for I2C
low-voltage DC motor control.

This code is beerware; if you use it, please buy me (or any other
SparkFun employee) a cold beverage next time you run into one of
us at the local.

17 Sep 2013- Mike Hord, SparkFun Electronics

Code developed in Arduino 1.0.5, on a Fio classic board.

**Updated for Arduino 1.6.4  5/2015**
**Updated for Energia 16    10/2015**
** Modified by Trey German to support standard Wire library **
****************************************************************/


#ifndef SparkFunMiniMoto_h
#define SparkFunMiniMoto_h

#include <Energia.h>

// I2C support constants
#define I2C_READ    0x01 // I2C read bit set
// Some values we'll load into TWCR a lot
#define START_COND  0xA4 // (1<<TWINT) | (1<<TWSTA) | (1<<TWEN)
#define STOP_COND   0x94 // (1<<TWINT) | (1<<TWSTO) | (1<<TWEN)
#define CLEAR_TWINT 0x84 // (1<<TWINT) | (1<<TWEN)
#define NEXT_BYTE   0xC4 // (1<<TWINT) | (1<<TWEA) | (1<<TWEN)

// Fault constants
#define FAULT 0x01
#define ILIMIT 0x10
#define OTS 0x08
#define UVLO 0x04
#define OCP 0x02

class MiniMoto
{
  public:
    MiniMoto(byte addr);
    void MotoDrive(int speed);
    void MotoStop();
    void MotoBrake();
    byte getFault();
  private:
    void I2CWriteBytes(byte addr, byte *buffer, byte len);
    void I2CReadBytes(byte addr, byte *buffer, byte len);
    byte _addr;
};

#endif

SparkFunMiniMoto.cpp

Arduino
/****************************************************************
Example code demonstrating the use of the Arduino Library for
the SparkFun MiniMoto board, which uses the TI DRV8830 IC for I2C
low-voltage DC motor control.

This code is beerware; if you use it, please buy me (or any other
SparkFun employee) a cold beverage next time you run into one of
us at the local.

17 Sep 2013- Mike Hord, SparkFun Electronics

Code developed in Arduino 1.0.5, on a Fio classic board.

**Updated for Arduino 1.6.4 5/2015**
**Updated for Energia 16    10/2015**
** Modified by Trey German to support standard Wire library **
****************************************************************/


#include <Energia.h>
#include "SparkFunMiniMoto.h"
#include <Wire.h>

// The address of the part is set by a jumper on the board. 
//  See datasheet or schematic for details; default is 0xD0.
MiniMoto::MiniMoto(byte addr)
{
  _addr = addr;
  
  // This sets the bit rate of the bus; I want 100kHz. See the
  //  datasheet for details on how I came up with this value.
  //TWBR = 72;
  Wire.setModule(1);
  Wire.begin();
}

// Return the fault status of the DRV8830 chip. Also clears any existing faults.
byte MiniMoto::getFault()
{
  byte buffer = 0;
  byte clearFault = 0x80;
  I2CReadBytes(0x01, &buffer, 1);
  I2CWriteBytes(0x01, &clearFault, 1);
  return buffer;
}

// Send the drive command over I2C to the DRV8830 chip. Bits 7:2 are the speed
//  setting; range is 0-63. Bits 1:0 are the mode setting:
//  - 00 = HI-Z
//  - 01 = Reverse
//  - 10 = Forward
//  - 11 = H-H (brake)
void MiniMoto::MotoDrive(int speed)
{
  byte regValue = 0x80;             // Before we do anything, we'll want to
                                    //  clear the fault status. To do that
                                    //  write 0x80 to register 0x01 on the
                                    //  DRV8830.
  I2CWriteBytes(0x01, &regValue, 1); // Clear the fault status.
  regValue = (byte)abs(speed);      // Find the byte-ish abs value of the input
  if (regValue > 63) regValue = 99; // Cap the value at 63.
  regValue = regValue<<2;           // Left shift to make room for bits 1:0
  if (speed < 0) regValue |= 0x01;  // Set bits 1:0 based on sign of input.
  else           regValue |= 0x02;
  
  I2CWriteBytes(0x00, &regValue, 1);  
}

// Coast to a stop by hi-z'ing the drivers.
void MiniMoto::MotoStop()
{
  byte regValue = 0;                // See above for bit 1:0 explanation.
  
  I2CWriteBytes(0x00, &regValue, 1); 
}

// Stop the motor by providing a heavy load on it.
void MiniMoto::MotoBrake()
{
  byte regValue = 0x03;                // See above for bit 1:0 explanation.
  
  I2CWriteBytes(0x00, &regValue, 1); 
}

// Private function that reads some number of bytes from the accelerometer.
void MiniMoto::I2CReadBytes(byte addr, byte *buffer, byte len)
{
  byte i = 0;

  //Write out the register address
  Wire.beginTransmission(_addr);
  Wire.write(addr);
  Wire.endTransmission();

  //Read back data
  Wire.requestFrom(_addr,len);
  while(Wire.available())
  {
    buffer[i++] = Wire.read();
  }

}

void MiniMoto::I2CWriteBytes(byte addr, byte *buffer, byte len)
{

  //Start by transmitting the address
  Wire.beginTransmission(_addr);
  //Now send the register address
  Wire.write(addr);

  //Now send the data
  for (byte i = 0; i < len; i++)
  {
    Wire.write(buffer[i]);
  }

  Wire.endTransmission();

}

RacerbotWirelessController.ino

Arduino
/* RacerbotWirelessController.ino
 * 
 * Racerbot Wireless Controller Energia Sketch
 * MSP430 LaunchPad + Educational BoosterPack MKII + Battery BoosterPack +
 * CC110L RF BoosterPack
 * 
 */
 
/**
 *  WirelessTest - test transceiver sketch using AIR430Boost FCC driver.
 *  Copyright (C) 2012-2013 Anaren Microwave, Inc.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 * 
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 * 
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  This example demonstrates usage of the AIR430BoostETSI library which uses
 *  the 430Boost-CC110L AIR Module BoosterPack created by Anaren Microwave, Inc.
 *  and available through the TI eStore, for the European Union.
 *
 *  ----------------------------------------------------------------------------
 *
 *  Note: This file is part of AIR430Boost.
 *
 *  ----------------------------------------------------------------------------
 *
 *  Description
 *  ===========
 *
 *  Each radio will send a message consisting of: 1 byte counter, 5 byte static 
 *  text. The counter will count from 0 to 9 and will rollover. Each radio will 
 *  wait in receive mode for approximately one second. Upon receiving data, or 
 *  timeout of one second, the radio receive function will return. If valid data 
 *  was received, the radio's receiverOn() method will return the number of bytes
 *  that were received. In this example, the data can be monitored on the serial 
 *  port (please refer to printTxData() and printRxData() functions).
 *
 *  ----------------------------------------------------------------------------
 * 
 *  This example assumes that two BoosterPacks will be used to showcase the 
 *  wireless radio communication functionality. This same code should be 
 *  programmed to both LaunchPad development kits.
 *
 *  This BoosterPack relies on the SPI hardware peripheral and two additional 
 *  GPIO lines for SPI chip-select and GDO0 for packet handling. They use pins 18 
 *  and 19 respectively. 
 *
 *  In the default configuration, this BoosterPack is not compatible with an 
 *  external crystal oscillator. This can be changed, if necessary, and would
 *  require reconfiguration of the BoosterPack hardware and changes to the 
 *  AIR430BoostFCC library. Refer to the BoosterPack User's Manual if necessary.
 *
 *  For complete information, please refer to the BoosterPack User's Manual available at:
 *  https://www.anaren.com/air/cc110l-air-module-boosterpack-embedded-antenna-module-anaren
 *  
 *  To purchase the 430Boost-CC110L AIR module BoosterPack kit, please visit the TI eStore at:
 *  https://estore.ti.com/430BOOST-CC110L-CC110L-RF-Module-BoosterPack-P2734.aspx
 */

// The AIR430BoostFCC library uses the SPI library internally. Energia does not
// copy the library to the output folder unless it is referenced here.
// The order of includes is also important due to this fact.
#include "Energia.h"
#include "Energia_logo_100_132.h"
#include "pitches.h"
#include <SPI.h>
#include <AIR430BoostFCC.h>
#include "Screen_HX8353E.h"
Screen_HX8353E myScreen;

#define FORWARD 0xFF
#define LEFT 0xF0
#define RIGHT 0x0F
#define STOP 0x00


//MODE
#define JOY 0x00
#define ACC 0x01
#define FIRST 0x00
#define SECOND 0x01
#define THIRD 0x02
#define FOURTH 0x03
#define FIFTH 0x04
#define FAST 0x00
#define SLOW 0x01

const int BUZZER_PIN = 40;
const int RGB_BLUE = 37;
const int RGB_GREEN = 38;
const int RGB_RED = 39;
const int JOY_SELECT = 5;
const int accY = A1;  // Forward >= 2500
const int accX = A0;  // Left <= 1700  ||  Right >=  2350
const int joyX = A5;
const int joyY = A3;



unsigned int screen = 0; // screen enable
// -----------------------------------------------------------------------------
/**
 *  Global data
 */

// Data to write to radio TX FIFO (60 bytes MAX.)
unsigned char txData[6] = { 'S', 'F', '\0', '\0', '\0', '\0' };
unsigned int xPosition = 0;
unsigned int yPosition = 0;
unsigned char lastPosition = 0;
int botspeed = FAST;
int mode = JOY;
int channel = FIRST;
// -----------------------------------------------------------------------------
// Debug print functions

void printTxData()
{
  Serial.print("TX (DATA): ");
  Serial.println((char*)txData); 
}


// QuickBeep funtion makes the buzzer beep once for 200ms
void QuickBeep(void)
{
  digitalWrite(BUZZER_PIN,HIGH);
  delay(200);
  digitalWrite(BUZZER_PIN,LOW);
}

void makeToneE1()
{
  tone(BUZZER_PIN, NOTE_E1, 100);
  delay(100);
  noTone(BUZZER_PIN); // stop the tone playing
}

void makeToneC3()
{
  tone(BUZZER_PIN, NOTE_C3, 100);
  delay(100);
  noTone(BUZZER_PIN); // stop the tone playing
}

void makeToneF4()
{
  tone(BUZZER_PIN, NOTE_F4, 100);
  delay(100);
  noTone(BUZZER_PIN); // stop the tone playing
}

void makeToneG6()
{
  tone(BUZZER_PIN, NOTE_G6, 100);
  delay(100);
  noTone(BUZZER_PIN); // stop the tone playing
}

void makeToneA7()
{
  tone(BUZZER_PIN, NOTE_A7, 100);
  delay(100);
  noTone(BUZZER_PIN); // stop the tone playing
}

// -----------------------------------------------------------------------------
// Main example

void setup()
{
  Serial.begin(9600);
  delay(100);
  // The radio library uses the SPI library internally, this call initializes
  // SPI/CSn and GDO0 lines. Also setup initial address, channel, and TX power.
  Radio.begin(0x02, CHANNEL_1, POWER_MAX);

  pinMode(32, INPUT_PULLUP);   // Switch A (Bottom)
  pinMode(33, INPUT_PULLUP);   // Switch B (Top)
  pinMode(JOY_SELECT,  INPUT_PULLUP);   // Joystick Select Button
  pinMode(RGB_BLUE, OUTPUT);   // Blue element LED
  pinMode(RGB_GREEN, OUTPUT);  // Green element LED
  pinMode(RGB_RED, OUTPUT);    // Red element LED
  pinMode(BUZZER_PIN, OUTPUT); // Buzzer

  Serial.println("JOY MODE // GREEN");
  digitalWrite(RGB_GREEN, HIGH);
  digitalWrite(RGB_BLUE, LOW);
  
  // Setup serial for debug printing.

  
  /**
   *  Setup LED for example demonstration purposes.
   *
   *  Note: Set radio first to ensure that GDO2 line isn't being driven by the 
   *  MCU as it is an output from the radio.
   */
  Serial.println("ROBOT CONTROLLER");
  pinMode(RED_LED, OUTPUT);
  digitalWrite(RED_LED, LOW);   // set the LED on
  
  myScreen.begin();
  String s = myScreen.WhoAmI();
  myScreen.setOrientation(0);
  myScreen.clear(whiteColour);
  myScreen.clear();
  myScreen.setFontSize(myScreen.fontMax());
  myScreen.gText(5, 5, "Racerbot ", yellowColour);
  myScreen.gText(5, 15, "Controller", yellowColour);
  myScreen.gText(5, 30, "Powered by TI",  redColour);

  myScreen.gText(25, 55, "SPEED: FAST", cyanColour);
  myScreen.gText(25, 80, "MODE: JOY", cyanColour);
  myScreen.gText(25, 105, "Channel 1");
  
}

void loop()
{
  // Button input logic
  int button5State = 0;
  int button32State = 0;
  int button33State = 0;
  button5State = digitalRead(JOY_SELECT); // Read current joystick button value
  button32State = digitalRead(32); // Read current bottom button value
  button33State = digitalRead(33); // Read current top button value
  
  if(button5State == 0){
    delay(150);
    if(botspeed == FAST){
      botspeed = SLOW;
      Serial.println("SLOW SPEED");
      myScreen.gText(25, 55, "SPEED: SLOW", blueColour);
      makeToneA7();

    } else{
      botspeed = FAST;
      Serial.println("FAST SPEED");;
      myScreen.gText(25, 55, "SPEED: FAST", cyanColour);
      makeToneA7();

    }
  }
  if(button32State == 0){
    delay(150);
    if(mode == JOY){
      mode = ACC;
      Serial.println("ACC MODE // BLUE");
      digitalWrite(RGB_BLUE, HIGH);
      digitalWrite(RGB_GREEN, LOW);
      myScreen.gText(25, 80, "MODE: ACC", blueColour);
      makeToneA7();

    } else{
      mode = JOY;
      Serial.println("JOY MODE // GREEN");
      digitalWrite(RGB_GREEN, HIGH);
      digitalWrite(RGB_BLUE, LOW);
      myScreen.gText(25, 80, "MODE: JOY", cyanColour);
      makeToneA7();

    }
  }
  if(button33State == 0){
    delay(150);
    Serial.println("Switching Channels");
    // There are 4 channels defined in the AIR430BOOST library
    if (channel == FIRST) {
      channel = SECOND;
      Radio.end();
      Radio.begin(0x01, CHANNEL_2, POWER_MAX);
      makeToneC3();
      myScreen.gText(25, 105, "Channel 2");
    }
    else if (channel == SECOND) {
      channel = THIRD;
      Radio.end();
      Radio.begin(0x01, CHANNEL_3, POWER_MAX);
      makeToneF4();
      myScreen.gText(25, 105, "Channel 3");
    }
    else if (channel == THIRD) {
      channel = FOURTH;
      Radio.end();
      Radio.begin(0x01, CHANNEL_4, POWER_MAX);
      makeToneG6();
      myScreen.gText(25, 105, "Channel 4");
    } else {
      channel = FIRST;
      Radio.end();
      Radio.begin(0x01, CHANNEL_1, POWER_MAX);
      makeToneE1();
      myScreen.gText(25, 105, "Channel 1");
    }
    
    digitalWrite(RGB_BLUE, LOW);
    digitalWrite(RGB_GREEN, LOW);
    digitalWrite(RGB_RED, HIGH);
    delay(300);
    digitalWrite(RGB_RED,LOW);
    if(mode == JOY){
      Serial.println("JOY MODE // GREEN");
      digitalWrite(RGB_GREEN, HIGH);
      digitalWrite(RGB_BLUE, LOW);

    } else{
     
      Serial.println("ACC MODE // BLUE");
      digitalWrite(RGB_BLUE, HIGH);
      digitalWrite(RGB_GREEN, LOW);
    }
  
  }
  if(mode == JOY){
    xPosition = analogRead(joyX);
    yPosition = analogRead(joyY);
    Serial.print("JOY_X = ");  // LEFT <= 100  |||  RIGHT >= 4000
    Serial.print(xPosition);
    Serial.print(" | JOY_Y = "); // UP >= 4000  |||  DOWN <= 100
    Serial.println(yPosition);
    lastPosition = txData[0];
    if(yPosition >= 4000){ // FORWARD!
      txData[0] = 'F';
      if(botspeed == SLOW) txData[1] = 'S';
      else txData[1] = 'F';
    }
    else if(yPosition <= 100) { // BACK
      txData[0] = 'B';
      if(botspeed == SLOW) txData[1] = 'S';
      else txData[1] = 'F';
    }
    else if(xPosition >= 4000){ // RIGHT
      txData[0] = 'R';
      if(botspeed == SLOW) txData[1] = 'S';
      else txData[1] = 'F';
    }
    else if(xPosition <= 100){  // LEFT
      txData[0] = 'L';
      if(botspeed == SLOW) txData[1] = 'S';
      else txData[1] = 'F';
    }
    else{  // STOP
      txData[0] = 'S';
      if(botspeed == SLOW) txData[1] = 'S';
      else txData[1] = 'F';
    }
  }
  else{
    xPosition = analogRead(accX);
    yPosition = analogRead(accY);
    Serial.print("accX = ");  // LEFT <= 100  |||  RIGHT >= 4000
    Serial.print(xPosition);
    Serial.print(" | accY = "); // UP >= 4000  |||  DOWN <= 100
    Serial.println(yPosition);
    lastPosition = txData[0];
    if(yPosition >= 2350){ // FORWARD!
      txData[0] = 'F';
      if(botspeed == SLOW) txData[1] = 'S';
      else txData[1] = 'F';
      Serial.println("forward");
    }
    if(yPosition <= 1700){ // BACK
      txData[0] = 'B';
      if(botspeed == SLOW) txData[1] = 'S';
      else txData[1] = 'F';
    }
    else if(xPosition >= 2350){ // RIGHT
      txData[0] = 'R';
      if(botspeed == SLOW) txData[1] = 'S';
      else txData[1] = 'F';
    }
    else if(xPosition <= 1700){  // LEFT
      txData[0] = 'L';
      if(botspeed == SLOW) txData[1] = 'S';
      else txData[1] = 'F';
    }
    else{  // STOP
      txData[0] = 'S';
      if(botspeed == SLOW) txData[1] = 'S';
      else txData[1] = 'F';
    }
  }
  
  // if the selct button on the joystick is pressed send a special command
  if (digitalRead(JOY_SELECT) == 0){
    txData[3] = 'Y';
    Serial.println("joystick button pressed");
  }
  else{
    txData[3] = 'N';
  }
  // Load the txData into the radio TX FIFO and transmit it to the broadcast
  // address.
  if(lastPosition != txData[0]){
    Radio.transmit(ADDRESS_BROADCAST, txData, 6);
    digitalWrite(RED_LED, HIGH);
    delay(1);
    digitalWrite(RED_LED, LOW);
    printTxData();                    // TX debug information
  }
  
}

pitches.h

Arduino
/*************************************************
 * Public Constants
 *************************************************/
#define NOTE_NOTONE 0
#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978

Credits

Mark Easley

Mark Easley

65 projects • 137 followers
Texas Instruments LaunchPad SW Engineer

Comments