Commit d66b9341 authored by Evan Raskob's avatar Evan Raskob

first check in of basic example

parent 84458c5c
/*
* Send and receive serial.
* The question is, what do you want your Arduino to do?
* It should be as simple as possible.. that forms your API.
* Maybe you just want to turn somethings on and off? Or control a motor speed?
*
* Then, what data do you want from it? And how often?
*/
const char stopChar = '\n'; //new line character
const long timeoutMs = 400; // timeout if message took too long
// if matching an exact message:
const char LEDONCommand[] = "ledon";
const char LEDOFFCommand[] = "ledoff";
long bytesReceived = 1;
/**
* Blink an LED
* */
void blink(int pin, int duration)
{
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
delay(duration);
digitalWrite(pin, LOW);
delay(duration);
}
/**
* Expects a string
* */
void handleMessage(char *message)
{
// handle the command.. blink or something?
if (strcmp(message,LEDONCommand) == 0) {
digitalWrite(LED_BUILTIN,HIGH);
}
else if (strcmp(message,LEDOFFCommand) == 0) {
digitalWrite(LED_BUILTIN,LOW);
}
else {
for (int i=0; i<4; i++)
{
blink(LED_BUILTIN,80);
}
}
////////////////////////////////////////////////
// useful for debugging - echo back what we got
Serial.print('[');
int msgLen = strlen(message);
for (int i=0; i< msgLen; i++)
{
Serial.print(message[i]);
}
Serial.println(']');
Serial.flush(); // pause everything and send - otherwise sometimes we get errors in receiving
//////////////////////////////////////////////
}
void setup()
{
// just a test of string comparisons
//
char cmdTest[] = {'l', 'e', 'd', 'o', 'n', '\0'};
if (strcmp(cmdTest, LEDONCommand) == 0)
{
for (int i=0; i<4; i++)
{
blink(LED_BUILTIN,400);
}
}
// set this as high as you can reliably run on your platform
Serial.begin(38400);
// wait for serial port to be ready
while (!Serial);
}
void loop()
{
// this returns the number of bytes available to read
const int totalBytesToRead = Serial.available();
if (totalBytesToRead > 0)
{
Serial.print("bytes left:");
Serial.println(totalBytesToRead);
int bytesToRead = totalBytesToRead;
const long startTime = millis(); // time we started checking for serial
// create empty message, leave room for 1 extra byte (string terminator) just in case
char messageReceived[totalBytesToRead+1];
boolean error = true; // might not get a full message...
while (bytesToRead > 0)
{
// read the current serial values into the buffer, in order
// this starts at 0 and ends at the length of our buffer - 1
int index = totalBytesToRead - bytesToRead;
bytesReceived++; // debugging - keep track of chars read
char newChar = (char)Serial.read();
//we've consumed one byte from the serial buffer this loop:
bytesToRead = bytesToRead - 1;
// stop if we've taken too much time!
if (millis() - startTime > timeoutMs){
bytesToRead = 0;
break;
}
// check if we've received the stop character
if (newChar == stopChar)
{
// echo it back
// char echoStr[index+2];
// strcpy(echoStr, messageReceived);
// echoStr[index+1] = '\0';
// Serial.println(echoStr);
// handle it
error = false;
// change end character to string terminator
messageReceived[index] = '\0'; // null terminator to make a proper string: https://www.tutorialspoint.com/cprogramming/c_strings.htm
bytesToRead = 0;
break;
}
// otherwise, just add it to the buffer
else {
messageReceived[index] = newChar;
}
// finally, keep going.
}
if (error)
{
for (int i=0; i<4; i++)
{
blink(LED_BUILTIN,30);
}
}
// success! do something:
else {
// note: we might want to do this in two stages, parse first then handle
handleMessage(messageReceived);
// debugging - optional
Serial.println(bytesReceived);
}
}
}
/************************************************************************************
GUI
************************************************************************************/
ControlP5 cp5;
// DropdownList serialddl;
// DropdownList baudddl;
ScrollableList serialddl;
ScrollableList baudddl;
Textlabel arduinoLabel;
Textlabel UDPLabel;
Textlabel incomingPacket;
Button startButton;
Button stopButton;
Button testButton;
Textfield ipAddressField;
Textfield incomingPortField;
Textfield outgoingPortField;
void setupGUI() {
//the ControlP5 object
cp5 = new ControlP5(this);
//start button
startButton = cp5.addButton("START")
.setPosition(200, 200)
.setSize(200, 19)
;
//stop button
stopButton = cp5.addButton("STOP")
.setPosition(200, 200)
.setSize(200, 19)
;
stopButton.hide();
//start button
testButton = cp5.addButton("TEST_ON")
.setPosition(100, 227)
.setSize(80, 16)
;
testButton = cp5.addButton("TEST_OFF")
.setPosition(186, 227)
.setSize(80, 16)
;
//start button
testButton = cp5.addButton("ERROR")
.setPosition(272, 227)
.setSize(80, 16)
;
//Serial Port selector
// serialddl = cp5.addDropdownList("SerialPort")
serialddl = cp5.addScrollableList("SerialPort")
.setPosition(50, 100)
.setSize(200, 200)
;
serialddl.setItemHeight(20);
serialddl.setBarHeight(15);
serialddl.getCaptionLabel().set("SELECT ARDUINO SERIAL PORT");
serialddl.getCaptionLabel().getStyle().marginTop = 3;
serialddl.getCaptionLabel().getStyle().marginLeft = 3;
serialddl.getValueLabel().getStyle().marginTop = 3;
//set the serial options
//String SerialList[] = Serial.list();
serialList = Serial.list();
for (int i=0; i<serialList.length; i++) {
String portName = serialList[i];
serialddl.addItem(portName, i);
}
if (serialList.length > 0)
serialddl.setValue(0);
//setup the baud list
// baudddl = cp5.addDropdownList("BaudRate")
baudddl = cp5.addScrollableList("BaudRate")
.setPosition(50, 50)
.setSize(200, 200)
;
baudddl.setItemHeight(20);
baudddl.setBarHeight(15);
baudddl.getCaptionLabel().set("SELECT THE BAUD RATE");
baudddl.getCaptionLabel().getStyle().marginTop = 3;
baudddl.getCaptionLabel().getStyle().marginLeft = 3;
baudddl.getValueLabel().getStyle().marginTop = 3;
//the baud options
for (int i=0; i<serialRateStrings.length; i++) {
String baudString = serialRateStrings[i];
baudddl.addItem(baudString, i);
}
baudddl.setValue(serialRateStrings.length - 1);
//udp IP/port
ipAddressField = cp5.addTextfield("IP address")
.setPosition(300, 30)
.setAutoClear(false)
.setText(ipAddress)
;
incomingPortField = cp5.addTextfield("Incoming Port Number")
.setPosition(300, 80)
.setAutoClear(false)
.setText(str(inPort))
;
outgoingPortField = cp5.addTextfield("Outgoing Port Number")
.setPosition(300, 130)
.setAutoClear(false)
.setText(str(outPort))
;
//text labels
arduinoLabel = cp5.addTextlabel("arduinoLabel")
.setText("Serial")
.setPosition(50, 10)
.setColorValue(0xffffff00)
.setFont(createFont("SansSerif", 11))
;
UDPLabel = cp5.addTextlabel("UDPLabel")
.setText("UDP")
.setPosition(300, 10)
.setColorValue(0xffffff00)
.setFont(createFont("SansSerif", 11))
;
incomingPacket = cp5.addTextlabel("incomingPacketLabel")
.setText("Incoming Packet")
.setPosition(210, 100)
.setColorValue(0xffffff00)
.setFont(createFont("SansSerif", 10))
;
incomingPacket.hide();
}
//hide all the controls and show the stop button
void hideControls() {
serialddl.hide();
baudddl.hide();
startButton.hide();
outgoingPortField.hide();
incomingPortField.hide();
ipAddressField.hide();
incomingPacket.show();
//show the stop button
stopButton.show();
}
void showControls() {
serialddl.show();
baudddl.show();
startButton.show();
outgoingPortField.show();
incomingPortField.show();
ipAddressField.show();
incomingPacket.hide();
//hide the stop button
stopButton.hide();
}
void controlEvent(ControlEvent theEvent) {
String eventName = theEvent.getName();
if (eventName == "SerialPort") {
//set the serial port
serialListNumber = int(theEvent.getValue());
} else if (eventName == "BaudRate") {
int index = int(theEvent.getValue());
baud = Integer.parseInt(serialRateStrings[index]);
} else
if (eventName == "IP address") {
ipAddressField.setFocus(false);
ipAddress = theEvent.getStringValue();
} else if (eventName == "Incoming Port Number") {
incomingPortField.setFocus(false);
inPort = Integer.parseInt(theEvent.getStringValue());
} else if (eventName == "Outgoing Port Number") {
outgoingPortField.setFocus(false);
outPort = Integer.parseInt(theEvent.getStringValue());
}
}
int inPort = 6449; // udp input, if needed (not used right now)
int outPort = 6448; // wekinator port
String ipAddress = "127.0.0.1"; // our computer
OscP5 oscP5;
NetAddress myRemoteLocation;
void setupOSC() {
inPort = Integer.parseInt(incomingPortField.getText());
oscP5 = new OscP5(this, inPort);
ipAddress = ipAddressField.getText();
outPort = Integer.parseInt(outgoingPortField.getText());
myRemoteLocation = new NetAddress(ipAddress, outPort);
}
void stopOSC()
{
oscP5.stop();
}
/**
* Handle incoming osc messages.
*/
void oscEvent(OscMessage theOscMessage) {
drawIncomingOSC();
/* print the address pattern and the typetag of the received OscMessage */
print("### received an osc message.");
print(" addrpattern: "+theOscMessage.addrPattern());
print(" typetag: "+theOscMessage.typetag());
print(" timetag: "+theOscMessage.timetag());
if (theOscMessage.checkAddrPattern("/tc")==true) {
/* check if the typetag is the right one. */
print(" TOTAL: " + theOscMessage);
if (theOscMessage.checkTypetag("sfiis")) {
/* parse theOscMessage and extract the values from the osc message arguments. */
String textValue = theOscMessage.get(0).stringValue();
float sizeValue = theOscMessage.get(1).floatValue();
int thirdValue = theOscMessage.get(2).intValue();
print("### received an osc message /test with typetag sfiis.");
println(" values: "+textValue+", "+sizeValue+", "+thirdValue);
return;
}
}
}
import netP5.*;
import oscP5.*;
import controlP5.*;
import processing.serial.*;
/*
* This example reads sensor data from an Arduino
* and relays it to another program using OSC.
*
* by Evan Raskob (e.raskob@gold.ac.uk)
*/
boolean applicationRunning = false;
//start everything
public void START() {
boolean success = true;
try {
setupOSC();
setupSerial();
}
catch (Exception e)
{
// SERIAL ERROR!
System.err.println("SERIAL ERROR::" + e);
success = false;
}
if (success)
{
hideControls();
applicationRunning = true;
}
}
public void STOP()
{
if (applicationRunning)
{
stopSerial();
stopOSC();
applicationRunning = false;
}
showControls();
}
public void TEST_ON()
{
if (applicationRunning)
{
serial.write("ledon" + stopChar);
}
println("finished");
}
public void TEST_OFF()
{
if (applicationRunning)
{
serial.write("ledoff" + stopChar);
}
println("finished");
}
public void ERROR()
{
if (applicationRunning)
{
serial.write("bad data" + stopChar);
// could also leave out the stopChar and see what happens!
}
}
/************************************************************************************
SETUP/DRAW
************************************************************************************/
void setup() {
// configure the screen size and frame rate
size(550, 250, P3D);
frameRate(30);
setupGUI();
}
void draw() {
background(128);
if (applicationRunning) {
drawIncomingPackets();
}
}
/************************************************************************************
VISUALIZING INCOMING PACKETS
************************************************************************************/
int lastSerialPacket = 0;
int lastOSCPacket = 0;
void drawIncomingPackets() {
//the serial packet
fill(0);
rect(75, 50, 100, 100);
//the udp packet
rect(325, 50, 100, 100);
int now = millis();
int lightDuration = 75;
if (now - lastSerialPacket < lightDuration) {
fill(255);
rect(85, 60, 80, 80);
}
if (now - lastOSCPacket < lightDuration) {
fill(255);
rect(335, 60, 80, 80);
}
}
void drawIncomingSerial() {
// println("drawIncomingSerial");
lastSerialPacket = millis();
}
void drawIncomingOSC() {
lastOSCPacket = millis();
}
/************************************************************************************
SERIAL
************************************************************************************/
//the Serial communcation to the Arduino
Serial serial;
final char stopChar = '\n'; // character for end of line
final String[] serialRateStrings = {
"300", "1200", "2400", "4800", "9600", "14400",
"19200", "28800", "38400", "57600", "115200"
};
String serialList[] = null;
int baud=0;
int serialListNumber = 2;
// we will store the incoming serial values in here
ArrayList<Byte> serialBuffer = new ArrayList<Byte>();
/**
* This handles the receiving of serial.
* @param {Serial} serial The serial port object
*/
void serialEvent(Serial serial) {
String input = serial.readString();
println("serial received: " + input);
String[] msgs = split(input, ',');
// TODO: handle message here!
}
void setupSerial() {
if (baud < 1)
{
// choose highest rate if none was selected
baud = int(serialRateStrings[serialRateStrings.length-1]);
}
if (serialList != null) {
serialListNumber = (int)serialddl.getValue();
println("opening " + serialList[serialListNumber]);
serial = new Serial(this, serialList[serialListNumber], baud);
serial.bufferUntil(stopChar);
}
}
void stopSerial() {
serial.stop();
}
/**
* VisualiseWekinatorOSC by Evan Raskob
* For visualising OSC messages from Arduino to Wekinator
*
* TODO: pause button
*/
import oscP5.*;
import netP5.*;
import controlP5.*;
final int OSC_PORT = 6448; // wekinator port for osc messages
final String OSC_HOST = "127.0.0.1"; // IP address of remote computer to send to
OscP5 oscP5;
ControlP5 gui;
Textarea oscReceivedTxt; // for displaying incoming OSC messages
void setup()
{
size(400, 400);
// start oscP5, listening for incoming messages at wekinator port
oscP5 = new OscP5(this, OSC_PORT);
gui = new ControlP5(this);
oscReceivedTxt = gui.addTextarea("txt")
.setPosition(width/10,height/10)
.setSize(8*width/10,8*height/10)
.setFont(createFont("arial",12))
.setLineHeight(14)
.setColor(color(10))
.setColorBackground(color(180,180,250))
.setColorForeground(color(255,200));
oscReceivedTxt.setText("Incoming OSC:");
}
void draw()
{