Close

Electronics - Teensy - Initial Code

A project log for Not Just Another Coffee Table

Custom coffee table with a DCC train track, automation, LEDs and a web interface

jack-flynnJack Flynn 10/01/2018 at 13:490 Comments

You can find the Teensy code at the following git-hub.

The main function of the Teensy is to control the physical side of the effects on the layout. For now I've setup an RGB led on my test bench with a Teensy 3.1. The code as it stands simply waits for incomming commands via serial-USB and then turns on or off the various pins related to the command. 

You can see the main loop here;

/*
 * ArduinoEffectsManager.ino
 *
 * Created: 9/26/2018 4:03:43 PM
 * Author: Admin
 */ 
#include "RGBManager.h"
#include "Comms_SerialExtended.h"
#include "HW_Pin.h"

Comms_SerialExtendedClass USBSerial;

HW_PinClass TeensyLED;
    
#define pinRGB_r 21
#define pinRGB_g 23
#define pinRGB_b 22

void setup()
{
    RGBManager.setup(pinRGB_r,pinRGB_g,pinRGB_b);
    USBSerial.setup();
    
    TeensyLED.setup(13);
    TeensyLED.SetPin(LOW);
    
    USBSerial._PacketLayout.StartChar = ':';
    
    Serial.println("Hello World from ArduinoEffectsManager");
    USBSerial._PrintIncomming = true;
}

void loop()
{
    if(USBSerial.Read())
    {
        switch(USBSerial.parseCommand())
        {
            case 1: RGBHex_Received(); break;
            case 2: RGBOutput_state(); break;
            case 3: LEDState(); break;
            
            default: Serial.println("Command Not Recognised. Data received;"); USBSerial.printLastPacket(); break; 
        }
    }

    RGBManager.Refresh();
    
    static unsigned long timer_handshake = millis();
    
    if(millis() - timer_handshake > 15000)
    {
        Serial.println("USB Handshake");
        timer_handshake = millis();
    }
    

}

//RGB Hex value command
// Changes stored colour values for RGB Manager class
void RGBHex_Received()
{
    byte hexVal[3] = {USBSerial.parseInt(PacketPosition1),USBSerial.parseInt(PacketPosition2),USBSerial.parseInt(PacketPosition3)};
    
    Serial.print("Hex value received;");
    for (int i = 0; i <3; i++)
    Serial.print(hexVal[i]);
    Serial.println();
    
    RGBManager.SetColours(hexVal[0], hexVal[1], hexVal[2]);

}

//RGB Output control command
// Enable/Disable the RGB LED output. Passes to RGBManager class
void RGBOutput_state()
{    
        boolean enable = USBSerial.parseInt(PacketPosition1);
        Serial.print("RGB Output State;");
        Serial.println(enable? "Enabled" : "Disabled");
        
        if(enable)
        RGBManager.Enable();
        else
        RGBManager.Disable();
}

//LED State command
void LEDState()
{
    boolean newState = USBSerial.parseInt(PacketPosition1);
    
    TeensyLED.SetPin(newState);
    
    Serial.print("Teensy LED State Change;");
    Serial.println(TeensyLED._Status? "On" : "Off");
}

So after some initial variable setup you can see that I'm setting up the USB port and pin outputs to allow for LED toggling and colour control of the RGB led. I'm using my own custom built USB serial library for handling the parsing of the in-coming commands. 

The serial command library data works on the basis of reading defined in-coming packets. with the following layout; 

<"Start Character" "Seperator" "Data1" "Seperator" "Data2" "Seperator" "End Character">

Or for the current setup 

<:,"Command","Data2","Data3", \n> 

The in-coming serial bytes trigger on the "start character" and finish on the "end character". Once the packet has been received it returns with a valid packet available ready for parsing. The "line seperator" in the library is used to pick out values from the string. 

Once a "Command" is parsed from the packet and used to decode which command has been called. By using <ints> as our data type in the packet it allows for the use of a switch statement which makes the command code nice and neat. 

Each command will have its own requirements for data parsing and thus this is taken care of in the called function. These functions then toggle leds or change the colour of the RGB led depending on what was received. A nicety of dealing with our data packets in ASCII form is that we can easily send these commands via the Arduino serial monitor and test the results. 

Finally a "USB Handshake" is fired periodically to ensure that data is flowing correctly during debugging.

Discussions