Skip to content

Instantly share code, notes, and snippets.

@Craigson
Created April 8, 2016 03:42
Show Gist options
  • Select an option

  • Save Craigson/45e3a4061114c5d2f565ad2b07e7d7d3 to your computer and use it in GitHub Desktop.

Select an option

Save Craigson/45e3a4061114c5d2f565ad2b07e7d7d3 to your computer and use it in GitHub Desktop.
drawbot test
#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/Serial.h"
#include "cinder/Log.h"
#include <sstream>
#define BUFSIZE 80
#define READ_INTERVAL 0.25
#define EST_INTERVAL 0.5
using namespace ci;
using namespace ci::app;
using namespace std;
class DrawBotTestApp : public App {
public:
void setup() override;
void keyDown( KeyEvent event) override;
void update() override;
void draw() override;
//PLOTTER FUNCTIONS
void connectToDevice();
void setPins();
void moveYaxis();
void moveXaxis();
void checkIncoming();
void checkPins();
void goToOrigin();
void addCommand(string _command);
void executeNextCommand();
void removePreviousCommand();
void establishConnection();
void clearCommandStack();
void executeStack();
//PLOTTER VARIABLES
bool atHomeX;
bool atHomeY;
bool paused;
bool receivedResponse;
bool checkedLimits;
bool commandStackEmpty;
bool executeCommands;
bool sendNext;
bool waiting;
bool connectionEstablished = false;
float xPosition; //distance from origin (in mm)
float yPosition; //distance from origin (in mm)
float stageWidth; //dictates maximum travel distance in the x-direction
float stageHeight; //dictates maximum travel distance in the y-direction
string currentCommand;
string portName;
std::vector<string> mCommandStack;
double connectionTimer;
//SERIAL STUFF
bool mSendSerialMessage;
SerialRef mSerial;
uint8_t mCounter;
string mLastString;
double mLastRead, mLastUpdate;
};
/*******************************************************
SETUP
*******************************************************/
void DrawBotTestApp::setup()
{
atHomeX = false;
atHomeY = false;
paused = false;
receivedResponse = false;
checkedLimits = false;
mCounter = 0;
mLastRead = 0;
mLastUpdate = 0;
mSendSerialMessage = false;
mCommandStack = {};
commandStackEmpty = true;
sendNext = false;
waiting = false;
connectToDevice();
}
/*******************************************************
MAIN UPDATE
*******************************************************/
void DrawBotTestApp::update()
{
//ESTABLISH THE INITIAL CONNECTION WITH THE BOARD, OR CHECK FOR INCOMING BYTES
// if (!connectionEstablished) establishConnection();
if (waiting) checkIncoming();
//CHECK IF THE COMMAND STAND IS EMPTY
mCommandStack.size() > 0 ? commandStackEmpty = false : commandStackEmpty = true;
//IF THE COMMAND STACK IS EMPTY, AND EXECUTECOMMANDS == TRUE, SEND THE NEXT COMMAND TO THE BOARD
if (executeCommands && !commandStackEmpty && !waiting) executeNextCommand();
}
/*******************************************************
MAIN DRAW
*******************************************************/
void DrawBotTestApp::draw()
{
gl::clear( Color( 0, 0, 0 ) );
}
/*******************************************************
CONNECT TO DEVICE
this method checks which port the board is attached to,
set's that as the portName variable, and attemps to
initialize the serial device
*******************************************************/
void DrawBotTestApp::connectToDevice()
{
for( const auto &dev : Serial::getDevices() )
{
//console() << "Device: " << dev.getName() << endl;
if (dev.getName().compare("cu.usbmodem1421") == 0) portName = dev.getName();
else if (dev.getName().compare("cu.usbmodem1411") == 0) portName = dev.getName();
}
cout << "Board is connected to port: " << portName << endl;
try {
Serial::Device dev = Serial::findDeviceByNameContains( portName );
mSerial = Serial::create( dev, 9600 );
cout << endl;
cout << "Serial Port Initialization Successful" << endl;
}
catch( SerialExc &exc ) {
CI_LOG_EXCEPTION( "coult not initialize the serial device", exc );
exit( -1 );
}
mSerial->flush();
}
/*******************************************************
ESTABLISH CONNECITON
*******************************************************/
void DrawBotTestApp::establishConnection()
{
if (mSerial->getNumBytesAvailable() > 0)
{
try
{
cout << endl;
cout<< " -- bytes available! --" << endl;
auto numBytes = mSerial->getNumBytesAvailable();
cout << "num bytes received: " << numBytes << endl;
uint8_t buffer[numBytes];
mSerial->readBytes(buffer, numBytes);
cout << "printing buffer contents: " << endl;
for (auto b : buffer) cout << "byte: " << b<< endl;
// cout << buffer << endl;
cout << endl;
cout << "Initial connection established" << endl;
connectionEstablished = true;
} catch( SerialTimeoutExc &exc ) {
CI_LOG_EXCEPTION( "timeout", exc );
}
} else {
double now = getElapsedSeconds();
double deltaTime = now - mLastUpdate;
mLastUpdate = now;
mLastRead += deltaTime;
if( mLastRead > READ_INTERVAL ) {
mSendSerialMessage = true;
mLastRead = 0.0;
}
}
}
/*******************************************************
KEYDOWN
*******************************************************/
void DrawBotTestApp::keyDown(KeyEvent event)
{
switch (event.getCode())
{
case 273:
cout << "Moving up!" << endl;
//mSerial->writeString("SM,1000,0,3000\r");
addCommand("SM,1000,0,3000\r");
break;
case 274:
cout << "Moving down!" << endl;
//mSerial->writeString("SM,1000,0,-3000\r");
addCommand("SM,1000,0,-3000\r");
break;
case 275:
cout << "Moving right!" << endl;
// mSerial->writeString("SM,1000,3000,0\r");
addCommand("SM,1000,3000,0\r");
break;
case 276:
cout << "Moving left!" << endl;
//mSerial->writeString("SM,1000,-3000,0\r");
addCommand("SM,1000,-3000,0\r");
break;
default:
break;
}
switch (event.getChar())
{
case 'c':
cout << "Adding 'Current Request' to Stack" << endl;
addCommand("qc\n\r");
break;
case 'n':
mSerial->writeString("SM,1500,0,3000\n\r");
// mSerial->writeString("\r");
break;
case 'm':
mSerial->writeString("SM,1500,0,-3000\n\r");
//mSerial->writeString("\r");
break;
case 'p':
checkPins();
break;
case 'o':
executeStack();
break;
case 's':
setPins();
break;
case 'f':
clearCommandStack();
break;
case 't':
cout << "test: requesting current" << endl;
mSerial->writeString("qc\n\r");
cout << "waiting = true" << endl;
waiting = true;
break;
case 'e':
executeCommands = !executeCommands;
executeCommands == true ? cout << "Execute Commands!" << endl : cout << "Not sending commands" << endl;
default:
break;
}
mSerial->flush();
}
/*******************************************************
CHECK INCOMING MESSAGES
*******************************************************/
void DrawBotTestApp::checkIncoming()
{
if (mSerial->getNumBytesAvailable() > 0)
{
try
{
cout << endl;
cout<< " -- bytes available! --" << endl;
auto numBytes = mSerial->getNumBytesAvailable();
cout << "num bytes received: " << numBytes << endl;
uint8_t buffer[numBytes];
mSerial->readBytes(buffer, numBytes);
cout << "printing buffer contents: " << endl;
for (auto b : buffer) cout << "byte: " << b<< endl;
// cout << buffer << endl;
cout << endl;
if (mCommandStack.size() > 0) removePreviousCommand();
waiting = false;
} catch( SerialTimeoutExc &exc ) {
CI_LOG_EXCEPTION( "timeout", exc );
}
}
}
/*******************************************************
SET I/O PINS
*******************************************************/
void DrawBotTestApp::setPins()
{
//SET PIN B0 AS AN INPUT FOR THE X-AXIS LIMIT SWITCH
cout << "setting pins" << endl;
addCommand("PD,B,0,1\r");
}
/*******************************************************
CHECK STATE OF I/O PINS
*******************************************************/
void DrawBotTestApp::checkPins()
{
cout << "checking input pins" << endl;
mCommandStack.push_back("PI,B,0");
}
/*******************************************************
ZERO AXES - MOVE TO ORIGN
*******************************************************/
void DrawBotTestApp::goToOrigin()
{
//THIS MOVES THE PEN TO THE ORIGIN
cout << "moving to origin" << endl;
checkPins();
checkIncoming();
mSerial->writeString("SM,10,-30,0\r");
}
/*******************************************************
ADD COMMAND TO THE COMMAND STACK
*******************************************************/
void DrawBotTestApp::addCommand(string _command)
{
mCommandStack.push_back(_command);
cout << "number of commands in stack: " << mCommandStack.size() << endl;
}
/*******************************************************
EXECUTE NEXT COMMAND
*******************************************************/
void DrawBotTestApp::executeNextCommand()
{
//BECAUSE THE VECTOR IS A FIFO STACK, WE NEED TO ACCESS THE COMMAN THAT'S AT THE BOTTOM OF THE STACK
double now = getElapsedSeconds();
double deltaTime = now - mLastUpdate;
mLastUpdate = now;
mLastRead += deltaTime;
if( mLastRead > EST_INTERVAL ) {
mSendSerialMessage = true;
mLastRead = 0.0;
}
// //ONLY SEND THE NEXT COMMAND IF WE'VE WAITED THE DESIRED AMOUNT OF TIME, AND IF WE'RE NOT SITTING WAITING FOR A RESPONSE FROM THE BOARD
// if (mSendSerialMessage)
// {
// mSerial->writeString(")
// }
}
/*******************************************************
REMOVE COMMAND FROM THE COMMAND STACK
*******************************************************/
void DrawBotTestApp::removePreviousCommand()
{
cout << "removing command from stack: " << *mCommandStack.begin();
if(mCommandStack.size() > 0.) mCommandStack.erase(mCommandStack.begin()); //remove the command from the stack
cout << "number of commands in stack is now: " << mCommandStack.size() << endl;
}
/*******************************************************
EXECUTE STACK
*******************************************************/
void DrawBotTestApp::executeStack()
{
cout << "executing " << mCommandStack.size() << " commands" << endl;
for (int i = 0; i < mCommandStack.size(); i++)
{
mSerial->writeString(mCommandStack[i]);
cout << "sending: " << mCommandStack[i] << endl;
}
cout << "flushing serial buffer" << endl;
//mSerial->flush();
cout << "clearing stack" << endl;
mCommandStack.clear();
cout << mCommandStack.size() << " commands left in stack" << endl;
}
/*******************************************************
CLEAR COMMAND STACK
*******************************************************/
void DrawBotTestApp::clearCommandStack()
{
cout << "Clearing " << mCommandStack.size() << " commands from the stack!" << endl;
if (mCommandStack.size() > 0) mCommandStack.clear();
cout << "There are now " << mCommandStack.size() << " commands in the stack!" << endl;
}
CINDER_APP( DrawBotTestApp, RendererGl )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment