first commit

This commit is contained in:
Alex
2013-06-09 13:19:56 +02:00
commit 06453416ed
21 changed files with 3326 additions and 0 deletions

22
.gitattributes vendored Normal file
View File

@@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

215
.gitignore vendored Normal file
View File

@@ -0,0 +1,215 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#############
## Windows detritus
#############
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg

36
Readme.txt Normal file
View File

@@ -0,0 +1,36 @@
Copyright 2011 by Alexander Balasch http://coolrobotprojects.blogspot.co.at/
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
this project has been inspired by:
http://pleasantsoftware.com/developer/3d/spherebot/
///////////////////////////////////////////////////////////////////////////////////
HOW TO:
1.) Upload the Arduino sketch.
(I have added an additional multiplicator to the y-Step calculation to
match my spherebot to the unicorn-script coordinates. You will maybe have to
do the same adjustment for your Spherebot)
(You will also have to redefine your pins accordingly to your electronics design)
2.) Start the Spherebot-UI.exe and connect to your Arduino
Warning for custom Firmwares: The send file function will only work if the arduino answers each sent command with a message
that contains "ok:" so that the next command is sent.

View File

@@ -0,0 +1,552 @@
/*
* Copyright 2011 by Eberhard Rensch <http://pleasantsoftware.com/developer/3d>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
* Part of this code is based on/inspired by the Helium Frog Delta Robot Firmware
* by Martin Price <http://www.HeliumFrog.com>
*
* !!!!!!!!
* This sketch needs the following non-standard libraries (install them in the Arduino library directory):
* SoftwareServo: http://www.arduino.cc/playground/ComponentLib/Servo
* TimerOne: http://www.arduino.cc/playground/Code/Timer1
* !!!!!!!!
*/
#include <TimerOne.h>
#include <SoftwareServo.h>
#include "StepperModel.h"
#define TIMER_DELAY 64
/*
* PINS
*/
/* ms1 | ms2
----------------
L | L -> Full Step
H | L -> Half Step
L | H -> Quarter Step
H | H -> Sixteenth Step
*/
#define XAXIS_VMS1 HIGH
#define XAXIS_VMS2 HIGH
#define YAXIS_VMS1 HIGH
#define YAXIS_VMS2 HIGH
#define YAXIS_DIR_PIN 14
#define YAXIS_STEP_PIN 15
#define YAXIS_ENABLE_PIN 21
#define YAXIS_MS1_PIN 19 //don´t make this connection!! ADC6 and ADC7 can not be used as a digital pin ( I made the pull up connection manually)
#define YAXIS_MS2_PIN 28
//#define YAXIS_MS3_PIN 18
#define YAXIS_ENDSTOP_PIN -1 //13
#define XAXIS_DIR_PIN 10
#define XAXIS_STEP_PIN 8
#define XAXIS_ENABLE_PIN 2
#define XAXIS_MS1_PIN 3
#define XAXIS_MS2_PIN 4
#define XAXIS_ENDSTOP_PIN -1 // <0 0> No Endstop!
#define SERVO_PIN 13
/*
* Other Configuration
*/
#define DEFAULT_PEN_UP_POSITION 35
#define XAXIS_MIN_STEPCOUNT -5.6*230000
#define XAXIS_MAX_STEPCOUNT 5*230000
#define DEFAULT_ZOOM_FACTOR 0.1808 // With a Zoom-Faktor of .65, I can print gcode for Makerbot Unicorn without changes.
// The zoom factor can be also manipulated by the propretiary code M402
/* --------- */
StepperModel xAxisStepper(XAXIS_DIR_PIN, XAXIS_STEP_PIN, XAXIS_ENABLE_PIN, XAXIS_ENDSTOP_PIN, XAXIS_MS1_PIN, XAXIS_MS2_PIN, XAXIS_VMS1, XAXIS_VMS2,
XAXIS_MIN_STEPCOUNT, XAXIS_MAX_STEPCOUNT, 200.0, 16);
StepperModel rotationStepper(YAXIS_DIR_PIN, YAXIS_STEP_PIN, YAXIS_ENABLE_PIN, YAXIS_ENDSTOP_PIN, YAXIS_MS1_PIN, YAXIS_MS2_PIN, YAXIS_VMS1, YAXIS_VMS2,
0, 0, 200.0, 16);
SoftwareServo servo;
boolean servoEnabled=true;
long intervals=0;
volatile long intervals_remaining=0;
volatile boolean isRunning=false;
// comm variables
const int MAX_CMD_SIZE = 256;
char buffer[MAX_CMD_SIZE]; // buffer for serial commands
char serial_char; // value for each byte read in from serial comms
int serial_count = 0; // current length of command
char *strchr_pointer; // just a pointer to find chars in the cmd string like X, Y, Z, E, etc
boolean comment_mode = false;
// end comm variables
// GCode States
double currentOffsetX = 0.;
double currentOffsetY = 0.;
boolean absoluteMode = true;
double feedrate = 300.; // mm/minute
double zoom = DEFAULT_ZOOM_FACTOR;
const double maxFeedrate = 2000.;
// ------
void setup()
{
Serial.begin(115200);
Serial.print("EBB 1.0\n");
clear_buffer();
servo.attach(SERVO_PIN);
servo.write(DEFAULT_PEN_UP_POSITION);
if(servoEnabled)
{
for(int i=0;i<100;i++)
{
SoftwareServo::refresh();
delay(4);
}
}
//--- Activate the PWM timer
Timer1.initialize(TIMER_DELAY); // Timer for updating pwm pins
Timer1.attachInterrupt(doInterrupt);
#ifdef AUTO_HOMING
xAxisStepper.autoHoming();
xAxisStepper.setTargetPosition(0.);
commitSteppers(maxFeedrate);
delay(2000);
xAxisStepper.enableStepper(false);
#endif
}
void loop() // input loop, looks for manual input and then checks to see if and serial commands are coming in
{
get_command(); // check for Gcodes
if(servoEnabled)
SoftwareServo::refresh();
}
//--- Interrupt-Routine: Move the steppers
void doInterrupt()
{
if(isRunning)
{
if (intervals_remaining-- == 0)
isRunning = false;
else
{
rotationStepper.doStep(intervals);
xAxisStepper.doStep(intervals);
}
}
}
void commitSteppers(double speedrate)
{
long deltaStepsX = xAxisStepper.delta;
if(deltaStepsX != 0L)
{
xAxisStepper.enableStepper(true);
}
long deltaStepsY = rotationStepper.delta;
if(deltaStepsY != 0L)
{
rotationStepper.enableStepper(true);
}
long masterSteps = (deltaStepsX>deltaStepsY)?deltaStepsX:deltaStepsY;
double deltaDistanceX = xAxisStepper.targetPosition-xAxisStepper.getCurrentPosition();
double deltaDistanceY = rotationStepper.targetPosition-rotationStepper.getCurrentPosition();
// how long is our line length?
double distance = sqrt(deltaDistanceX*deltaDistanceX+deltaDistanceY*deltaDistanceY);
// compute number of intervals for this move
double sub1 = (60000.* distance / speedrate);
double sub2 = sub1 * 1000.;
intervals = (long)sub2/TIMER_DELAY;
intervals_remaining = intervals;
const long negative_half_interval = -intervals / 2;
rotationStepper.counter = negative_half_interval;
xAxisStepper.counter = negative_half_interval;
// Serial.print("Speedrate:");
// Serial.print(speedrate, 6);
// Serial.print(" dX:");
// Serial.print(deltaStepsX);
// Serial.print(" dY:");
// Serial.print(deltaStepsY);
// Serial.print(" masterSteps:");
// Serial.print(masterSteps);
// Serial.print(" dDistX:");
// Serial.print(deltaDistanceX);
// Serial.print(" dDistY:");
// Serial.print(deltaDistanceY);
// Serial.print(" distance:");
// Serial.print(distance);
// Serial.print(" sub1:");
// Serial.print(sub1, 6);
// Serial.print(" sub2:");
// Serial.print(sub2, 6);
// Serial.print(" intervals:");
// Serial.print(intervals);
// Serial.print(" negative_half_interval:");
// Serial.println(negative_half_interval);
// Serial.print("Y currentStepCount:");
// Serial.print(rotationStepper.currentStepcount);
// Serial.print(" targetStepCount:");
// Serial.println(rotationStepper.targetStepcount);
isRunning=true;
}
void get_command() // gets commands from serial connection and then calls up subsequent functions to deal with them
{
if (!isRunning && Serial.available() > 0) // each time we see something
{
serial_char = Serial.read(); // read individual byte from serial connection
if (serial_char == '\n' || serial_char == '\r') // end of a command character
{
buffer[serial_count]=0;
process_commands(buffer, serial_count);
clear_buffer();
comment_mode = false; // reset comment mode before each new command is processed
//Serial.write("process: command");
}
else // not end of command
{
if (serial_char == ';' || serial_char == '(') // semicolon signifies start of comment
{
comment_mode = true;
}
if (comment_mode != true) // ignore if a comment has started
{
buffer[serial_count] = serial_char; // add byte to buffer string
serial_count++;
if (serial_count > MAX_CMD_SIZE) // overflow, dump and restart
{
clear_buffer();
Serial.flush();
}
}
else
{
}
}
}
}
void clear_buffer() // empties command buffer from serial connection
{
serial_count = 0; // reset buffer placement
}
boolean getValue(char key, char command[], double* value)
{
// find key parameter
strchr_pointer = strchr(buffer, key);
if (strchr_pointer != NULL) // We found a key value
{
*value = (double)strtod(&command[strchr_pointer - command + 1], NULL);
return true;
}
return false;
}
void check_for_version_controll(char command)
{
if(command == 'v')
{
Serial.print("EBB 1.0\n");
}
}
void process_commands(char command[], int command_length) // deals with standardized input from serial connection
{
if(command_length == 1)
{
check_for_version_controll(command[0]);
}
if (command_length>0 && command[0] == 'G') // G code
{
//Serial.print("proces G: \n");
int codenum = (int)strtod(&command[1], NULL);
double tempX = xAxisStepper.getCurrentPosition();
double tempY = rotationStepper.getCurrentPosition();
double xVal;
boolean hasXVal = getValue('X', command, &xVal);
if(hasXVal) xVal*=zoom*1.71/2; //this factor is for correction to meet the unicorn coordinates
double yVal;
boolean hasYVal = getValue('Y', command, &yVal);
if(hasYVal) yVal*=zoom;
double iVal;
boolean hasIVal = getValue('I', command, &iVal);
if(hasIVal) iVal*=zoom;
double jVal;
boolean hasJVal = getValue('J', command, &jVal);
if(hasJVal) jVal*=zoom;
double rVal;
boolean hasRVal = getValue('R', command, &rVal);
if(hasRVal) rVal*=zoom;
double pVal;
boolean hasPVal = getValue('P', command, &pVal);
getValue('F', command, &feedrate);
xVal+=currentOffsetX;
yVal+=currentOffsetY;
if(absoluteMode)
{
if(hasXVal)
tempX=xVal;
if(hasYVal)
tempY=yVal;
}
else
{
if(hasXVal)
tempX+=xVal;
if(hasYVal)
tempY+=yVal;
}
switch(codenum)
{
case 0: // G0, Rapid positioning
xAxisStepper.setTargetPosition(tempX);
rotationStepper.setTargetPosition(tempY);
commitSteppers(maxFeedrate);
break;
case 1: // G1, linear interpolation at specified speed
xAxisStepper.setTargetPosition(tempX);
rotationStepper.setTargetPosition(tempY);
commitSteppers(feedrate);
break;
case 2: // G2, Clockwise arc
case 3: // G3, Counterclockwise arc
if(hasIVal && hasJVal)
{
double centerX=xAxisStepper.getCurrentPosition()+iVal;
double centerY=rotationStepper.getCurrentPosition()+jVal;
drawArc(centerX, centerY, tempX, tempY, (codenum==2));
}
else if(hasRVal)
{
//drawRadius(tempX, tempY, rVal, (codenum==2));
}
break;
case 4: // G4, Delay P ms
if(hasPVal)
{
unsigned long endDelay = millis()+ (unsigned long)pVal;
while(millis()<endDelay)
{
delay(1);
if(servoEnabled)
SoftwareServo::refresh();
}
}
break;
case 21: // G21 metric
break;
case 90: // G90, Absolute Positioning
absoluteMode = true;
break;
case 91: // G91, Incremental Positioning
absoluteMode = false;
break;
case 92: // G92 homing
break;
}
}
else if (command_length>0 && command[0] == 'M') // M code
{
//Serial.print("proces M:\n");
double value;
int codenum = (int)strtod(&command[1], NULL);
switch(codenum)
{
case 18: // Disable Drives
xAxisStepper.resetStepper();
rotationStepper.resetStepper();
break;
case 300: // Servo Position
if(getValue('S', command, &value))
{
servoEnabled=true;
if(value<0.)
value=0.;
else if(value>180.)
{
value=DEFAULT_PEN_UP_POSITION;
servo.write((int)value);
for(int i=0;i<100;i++)
{
SoftwareServo::refresh();
delay(4);
}
servoEnabled=false;
}
servo.write((int)value);
}
break;
case 400: // Propretary: Reset X-Axis-Stepper settings to new object diameter
if(getValue('S', command, &value))
{
xAxisStepper.resetSteppersForObjectDiameter(value);
xAxisStepper.setTargetPosition(0.);
commitSteppers(maxFeedrate);
delay(2000);
xAxisStepper.enableStepper(false);
}
break;
case 401: // Propretary: Reset Y-Axis-Stepper settings to new object diameter
if(getValue('S', command, &value))
{
rotationStepper.resetSteppersForObjectDiameter(value);
rotationStepper.setTargetPosition(0.);
commitSteppers(maxFeedrate);
delay(2000);
rotationStepper.enableStepper(false);
}
break;
case 402: // Propretary: Reset Y-Axis-Stepper settings to new object diameter
if(getValue('S', command, &value))
{
zoom = value/100;
}
break;
}
}
//done processing commands
if (Serial.available() <= 0) {
Serial.print("ok:");
Serial.println(command);
Serial.print("\n");
}
}
/* This code was ported from the Makerbot/ReplicatorG java sources */
void drawArc(double centerX, double centerY, double endpointX, double endpointY, boolean clockwise)
{
// angle variables.
double angleA;
double angleB;
double angle;
double radius;
double length;
// delta variables.
double aX;
double aY;
double bX;
double bY;
// figure out our deltas
double currentX = xAxisStepper.getCurrentPosition();
double currentY = rotationStepper.getCurrentPosition();
aX = currentX - centerX;
aY = currentY - centerY;
bX = endpointX - centerX;
bY = endpointY - centerY;
// Clockwise
if (clockwise) {
angleA = atan2(bY, bX);
angleB = atan2(aY, aX);
}
// Counterclockwise
else {
angleA = atan2(aY, aX);
angleB = atan2(bY, bX);
}
// Make sure angleB is always greater than angleA
// and if not add 2PI so that it is (this also takes
// care of the special case of angleA == angleB,
// ie we want a complete circle)
if (angleB <= angleA)
angleB += 2. * M_PI;
angle = angleB - angleA;
// calculate a couple useful things.
radius = sqrt(aX * aX + aY * aY);
length = radius * angle;
// for doing the actual move.
int steps;
int s;
int step;
// Maximum of either 2.4 times the angle in radians
// or the length of the curve divided by the curve section constant
steps = (int)ceil(max(angle * 2.4, length));
// this is the real draw action.
double newPointX = 0.;
double newPointY = 0.;
for (s = 1; s <= steps; s++) {
// Forwards for CCW, backwards for CW
if (!clockwise)
step = s;
else
step = steps - s;
// calculate our waypoint.
newPointX = centerX + radius * cos(angleA + angle * ((double) step / steps));
newPointY= centerY + radius * sin(angleA + angle * ((double) step / steps));
// start the move
xAxisStepper.setTargetPosition(newPointX);
rotationStepper.setTargetPosition(newPointY);
commitSteppers(feedrate);
while(isRunning)
{
delay(1);
if(servoEnabled)
SoftwareServo::refresh();
};
}
}
/* Make life easier for vim users */
/* vim:set filetype=cpp: */

View File

@@ -0,0 +1,179 @@
/*
* Copyright 2011 by Eberhard Rensch <http://pleasantsoftware.com/developer/3d>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "StepperModel.h"
#include "Arduino.h"
/*
* inEnablePin < 0 => No Endstop
*/
StepperModel::StepperModel(int inDirPin, int inStepPin, int inEnablePin, int inEndStopPin,int inMs1Pin, int inMs2Pin, bool vms1,bool vms2,
long minSC, long maxSC,
double in_kStepsPerRevolution, int in_kMicroStepping)
{
kStepsPerRevolution=in_kStepsPerRevolution;
kMicroStepping=in_kMicroStepping;
dirPin = inDirPin;
stepPin = inStepPin;
enablePin = inEnablePin;
endStopPin = inEndStopPin;
ms1Pin = inMs1Pin;
ms2Pin = inMs2Pin;
minStepCount=minSC;
maxStepCount=maxSC;
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(enablePin, OUTPUT);
pinMode(ms1Pin, OUTPUT);
pinMode(ms2Pin, OUTPUT);
if(endStopPin>=0)
pinMode(endStopPin, INPUT);
digitalWrite(dirPin, LOW);
digitalWrite(stepPin, LOW);
digitalWrite(ms1Pin, vms1);
digitalWrite(ms2Pin, vms2);
currentStepcount=0;
targetStepcount=0;
steps_per_mm = (int)((kStepsPerRevolution/(45.*M_PI))*kMicroStepping+0.5); // default value for a "normal" egg (45 mm diameter)
enableStepper(false);
}
void StepperModel::resetSteppersForObjectDiameter(double diameter)
{
// Calculate the motor steps required to move per mm.
steps_per_mm = (int)((kStepsPerRevolution/(diameter*M_PI))*kMicroStepping+0.5);
if(endStopPin>=0)
{
#ifdef AUTO_HOMING
autoHoming();
#endif
enableStepper(false);
}
else
resetStepper();
}
long StepperModel::getStepsForMM(double mm)
{
long steps = (long)(steps_per_mm*mm);
// Serial.print("steps for ");
// Serial.print(mm);
// Serial.print(" mm: ");
// Serial.println(steps);
return steps;
}
/* Currently unused */
/*
void StepperModel::setTargetStepcount(long tsc)
{
targetPosition = (double)tsc/steps_per_mm;
targetStepcount = tsc;
delta = targetStepcount-currentStepcount;
direction = true;
if (delta != 0) {
enableStepper(true);
}
if (delta < 0) {
delta = -delta;
direction = false;
}
}*/
void StepperModel::setTargetPosition(double pos)
{
targetPosition = pos;
targetStepcount = getStepsForMM(targetPosition);
//Serial.println(targetStepcount);
delta = targetStepcount-currentStepcount;
direction = true;
if (delta != 0) {
enableStepper(true);
}
if (delta < 0) {
delta = -delta;
direction = false;
}
}
double StepperModel::getCurrentPosition()
{
return (double)currentStepcount/steps_per_mm;
}
void StepperModel::enableStepper(bool enabled)
{
digitalWrite(enablePin, !enabled);
}
void StepperModel::resetStepper()
{
enableStepper(false);
currentStepcount=0;
targetStepcount=0;
delta=0;
}
void StepperModel::doStep(long intervals)
{
counter += delta;
if (counter >= 0) {
digitalWrite(dirPin, direction?HIGH:LOW);
counter -= intervals;
if (direction) {
if(maxStepCount==0 || currentStepcount<=maxStepCount)
{
digitalWrite(stepPin, HIGH);
currentStepcount++;
}
} else {
if(minStepCount==0 || currentStepcount>=minStepCount)
{
digitalWrite(stepPin, HIGH);
currentStepcount--;
}
}
digitalWrite(stepPin, LOW);
}
}
#ifdef AUTO_HOMING
void StepperModel::autoHoming()
{
enableStepper(true);
digitalWrite(dirPin, LOW);
while(digitalRead(endStopPin))
{
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
delay(1);
}
currentStepcount= minStepCount-16;
}
#endif

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2011 by Eberhard Rensch <http://pleasantsoftware.com/developer/3d>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef STEPPERMODEL
#define STEPPERMODEL
// Uncomment if You have Autohoming:
//#define AUTO_HOMING
class StepperModel
{
private:
int dirPin;
int stepPin;
int enablePin;
int ms1Pin;
int ms2Pin;
int endStopPin;
long minStepCount;
long maxStepCount;
double steps_per_mm;
double kStepsPerRevolution;
int kMicroStepping;
volatile long currentStepcount;
volatile long targetStepcount;
volatile bool direction;
long getStepsForMM(double mm);
public:
volatile long delta;
volatile long counter;
double targetPosition;
StepperModel(int inDirPin, int inStepPin, int inEnablePin, int inEndStopPin,int inMs1Pin, int inMs2Pin,bool vms1,bool vms2,
long minSC, long maxSC,
double in_kStepsPerRevolution, int in_kMicroStepping);
void resetSteppersForObjectDiameter(double diameter);
#ifdef AUTO_HOMING
void autoHoming();
#endif
void setTargetPosition(double pos);
double getCurrentPosition();
void enableStepper(bool enabled);
void resetStepper();
void doStep(long intervals);
};
#endif

View File

@@ -0,0 +1,25 @@
# Gnuplot Session
#
# Erste Spalte=x, Zweite=y
# Ei Spitze zeigt nach rechts (positive x)
#
# plot "egg-displace.dat" using 1:2 title "Ei"
# ==> graph looks like a parabola
# f(x)=a*x*x + b*x + c
# fit f(x) "egg-displace.dat" using 1:2 via a,b,c
# a=0.00795338
# b=0.0734545
# c=0.15711
# plot "egg-displace.dat" using 1:2 title "Ei" with lines, f(x)
# ==> fits reasonable well
-25 3
-20 2
-15 1
-10 0.5
-5 0.1
0 0
5 0.5
10 1.5
15 3
20 5
25 7

View File

@@ -0,0 +1,51 @@
v0.1
This is the firmware for an EggBot-style SphereBot.
The firmware directly interprets GCode send over the serial port.
There will be more information on the SphereBot at http://pleasantsoftware.com/developer/3d (in the near future...)
!!!!!!!!
This sketch needs the following non-standard libraries (install them in the Arduino library directory):
SoftwareServo: http://www.arduino.cc/playground/ComponentLib/Servo
TimerOne: http://www.arduino.cc/playground/Code/Timer1
!!!!!!!!
Copyright 2011 by Eberhard Rensch <http://pleasantsoftware.com/developer/3d>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Part of this code is based on/inspired by the Helium Frog Delta Robot Firmware
by Martin Price <http://www.HeliumFrog.com>
To create tags File: ctags --langmap="C++:+.pde" S*
GCode commands:
G90 Absolut modus
G91 Icremental modus:
M300S0 Servo 0 degree
M300S90 Servo 90 degree
M18 Stepper off
G0X0Y40 Rapid movement (pen 0mm, rotation 40mm)
G1X40Y0 Slower movement (pen 40mm, rotation 0mm)
G1Y10F660 Movement with feed 660mm/s (rotation 10mm)
; Comment
( .. ) Comment

BIN
Spherebot_UI.exe Normal file

Binary file not shown.

Submodule Spherebot_UI/3rdparty/qextserialport added at 0394a5d33b

View File

@@ -0,0 +1,28 @@
#-------------------------------------------------
#
# Project created by QtCreator 2013-05-30T07:01:31
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Spherebot_UI
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
spherebot.cpp \
txthread.cpp
include(3rdparty/qextserialport/src/qextserialport.pri)
HEADERS += mainwindow.h \
spherebot.h \
txthread.h
FORMS += mainwindow.ui
CONFIG += static

13
Spherebot_UI/main.cpp Normal file
View File

@@ -0,0 +1,13 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.setOrganizationName("thunderbug1");
MainWindow w;
w.setWindowTitle("Spherebot control");
w.show();
return app.exec();
}

350
Spherebot_UI/mainwindow.cpp Normal file
View File

@@ -0,0 +1,350 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
resetPortList();
sendState = false;
rxTimer = new QTimer(this);
//connect( bot.port, SIGNAL(readyRead()), this, SLOT(receiveData()) );
connect( rxTimer,SIGNAL(timeout()),this,SLOT(receiveData()));
connect( &bot, SIGNAL(dataSent(QString)),this, SLOT(sendData(QString)));
connect(this,SIGNAL(receivedLine(QString)),&Transceiver,SLOT(checkResponse(QString)));
connect(&Transceiver,SIGNAL(progressChanged(int)),this,SLOT(refreshSendProgress(int)));
connect(&Transceiver,SIGNAL(fileTransmitted()),this,SLOT(finishedTransmission()));
}
MainWindow::~MainWindow()
{
qDebug()<<"delete main window";
QSettings settings(nameSettingsFile, QSettings::NativeFormat);
QString tmp = (ui->portBox->currentText());
settings.setValue("portName", tmp);
delete ui;
}
///////////////////////////////////////////////////////////////////////////////
void MainWindow::loadFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
statusBar()->showMessage(tr("File loaded"), 2000);
ui->fileTextEdit->setText(file.readAll());
}
bool MainWindow::saveFile(const QString &fileName)
//! [44] //! [45]
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot write file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return false;
}
QTextStream out(&file);
out<<ui->fileTextEdit->toPlainText();
statusBar()->showMessage(tr("File saved"), 2000);
return true;
}
void MainWindow::receiveData()
{
if(bot.port->bytesAvailable())
{
//qDebug()<< "Read line";
QString line =bot.port->readLine(1024);
line.chop(1);
emit receivedLine(line);
ui->rxList->insertItem(0,line);
}
}
void MainWindow::refreshSendProgress(int value)
{
ui->fileSendProgressBar->setValue(value);
}
void MainWindow::finishedTransmission()
{
ui->sendFileButton->setText("Send File");
ui->controllBox->setEnabled(true);
ui->fileSendProgressBar->setEnabled(false);
statusBar()->showMessage(tr("File successfully sent"));
sendState = false;
}
///////////////////////////////////////////////////////////////////
void MainWindow::on_connectButton_clicked()
{
if(bot.isConnected())
{
//disconnect
rxTimer->stop();
bot.disconnectWithBot();
ui->connectButton->setChecked(false);
ui->connectButton->setText("Connect");
ui->controllBox->setEnabled(false);
ui->resetButton->setEnabled(true);
ui->portBox->setEnabled(true);
ui->sendFileButton->setEnabled(false);
ui->eggSlider->setValue(0);
ui->diameterSlider->setValue(DEFAULTDIAMETER);
ui->penSlider->setValue(0);
ui->servoSlider->setValue(DEFAULTPENUP);
ui->FeedratespinBox->setValue(DEFAULTFEEDRATE);
ui->fileSendProgressBar->setValue(0);
sendState = 0;
ui->sendFileButton->setText("Send File");
}
else if(bot.connectWithBot(ui->portBox->currentText()))
{
//successfully connected
rxTimer->start(2);
qDebug()<<"Start Timer";
ui->connectButton->setChecked(true);
ui->controllBox->setEnabled(true);
ui->portBox->setEnabled(false);
ui->resetButton->setEnabled(false);
ui->connectButton->setText("Disconnect");
if(!ui->fileTextEdit->toPlainText().isEmpty()) ui->sendFileButton->setEnabled(true);
}
else
{
}
}
void MainWindow::resetPortList()
{
portList =serialEnumerator.getPorts();
ui->portBox->clear();
for(int i=0;i<portList.size();i++)
{
ui->portBox->addItem(portList[i].portName);
}
}
void MainWindow::on_resetButton_clicked()
{
resetPortList();
}
void MainWindow::sendData(QString data)
{
ui->txList->insertItem(0,data);
}
void MainWindow::on_sendString_editingFinished()
{
if(!bot.send(ui->sendString->text()))
{
//sendData(ui->sendString->text());
}
else
{
qDebug()<<bot.port->errorString();
sendData("Error while sending Data!");
}
}
void MainWindow::on_sendButton_clicked()
{
if(!bot.send(ui->sendString->text()))
{
//sendData(ui->sendString->text());
}
else
{
qDebug()<<bot.port->errorString();
//sendData("Error while sending Data!");
}
}
void MainWindow::on_servoSlider_sliderMoved(int position)
{
//ui->servospinBox->setValue(position);
QString tmp = ("M300 S" + QString::number(position)+"\n");
bot.send(tmp);
//sendData(tmp);
}
void MainWindow::on_servospinBox_valueChanged(int arg1)
{
ui->servoSlider->setValue(arg1);
QString tmp = ("M300 S" + QString::number(arg1)+"\n");
bot.send(tmp);
}
void MainWindow::on_penRotationBox_valueChanged(int arg1)
{
QString tmp = ("G1 Y" + QString::number((double)arg1));
bot.send(tmp);
ui->penSlider->setValue(arg1);
}
void MainWindow::on_penSlider_valueChanged(int value)
{
ui->penRotationBox->setValue(value);
}
void MainWindow::on_eggSlider_valueChanged(int value)
{
ui->eggRotationBox->setValue(value);
}
void MainWindow::on_eggRotationBox_valueChanged(int arg1)
{
QString tmp = ("G1 X" + QString::number((double)arg1)+"\n");
bot.send(tmp);
ui->eggSlider->setValue(arg1);
}
void MainWindow::on_loadFileButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
loadFile(fileName);
if(!ui->fileTextEdit->toPlainText().isEmpty())
{
setWindowTitle("Spherebot Controll File: " + fileName);
ui->fileName->setText(QFileInfo(fileName).fileName());
}
else ui->sendButton->setEnabled(false);
}
void MainWindow::on_saveFileButton_clicked()
{
saveFile(curFile);
ui->saveFileButton->setEnabled(false);
}
QString removeComments(QString input);
void MainWindow::on_fileTextEdit_textChanged()
{
ui->saveFileButton->setEnabled(true);
ui->outputText->setText(removeComments((ui->fileTextEdit->toPlainText())));
if(!ui->fileTextEdit->toPlainText().isEmpty())
{
setWindowTitle("Spherebot Controll");
ui->fileName->setText("");
if(bot.isConnected()) ui->sendFileButton->setEnabled(true);
else ui->sendButton->setEnabled(false);
}
}
void MainWindow::on_sendFileButton_clicked()
{
QScrollBar *vScrollBar = ui->fileTextEdit->verticalScrollBar();
qDebug()<<"enter button code";
switch(sendState)
{
case 0: //start to send
qDebug()<<"start sending";
sendState = 1;
ui->controllBox->setEnabled(false);
ui->fileSendProgressBar->setEnabled(true);
ui->sendFileButton->setText("Stop");
ui->controllBox->setEnabled(false);
ui->sendButton->setEnabled(false);
Transceiver.set(ui->fileTextEdit->toPlainText(),this->bot);
qDebug()<<"tx is set";
Transceiver.run();
statusBar()->showMessage(tr("Sending File"));
break;
case 1: //stop the print
qDebug()<< "You have stoped sending";
sendState = 2;
ui->restartButton->setEnabled(true);
ui->sendFileButton->setText("Continue");
ui->controllBox->setEnabled(true);
ui->sendButton->setEnabled(true);
vScrollBar->setValue(Transceiver.getLineCounter());
Transceiver.checkSendBufferTimer->stop();
break;
case 2: //continue
sendState = 1;
Transceiver.checkSendBufferTimer->start(SENDBUFFERINTERVAL);
ui->restartButton->setEnabled(false);
ui->sendFileButton->setText("Stop");
ui->controllBox->setEnabled(false);
ui->sendButton->setEnabled(false);
break;
}
qDebug()<<"leave button code";
}
void MainWindow::on_restartButton_clicked()
{
sendState = 1;
ui->controllBox->setEnabled(false);
ui->fileSendProgressBar->setEnabled(true);
ui->sendFileButton->setText("Stop");
ui->controllBox->setEnabled(false);
ui->sendButton->setEnabled(false);
Transceiver.set(ui->fileTextEdit->toPlainText(),this->bot);
qDebug()<<"tx is set";
Transceiver.run();
statusBar()->showMessage(tr("Sending File"));
}
void MainWindow::on_servoFeedrateSlider_valueChanged(int value)
{
QString tmp = ("G1 F" + QString::number(value)+"\n");
bot.send(tmp);
}
void MainWindow::on_setDiameterButton_clicked()
{
QString tmp = ("M400 S" + QString::number(ui->diameterSlider->value())+"\n");
bot.send(tmp);
tmp.clear();
tmp = ("M401 S" + QString::number(ui->diameterSlider->value())+"\n");
bot.send(tmp);
}
void MainWindow::on_undoButton_clicked()
{
ui->fileTextEdit->undo();
}
void MainWindow::on_redoButton_clicked()
{
ui->fileTextEdit->redo();
}
void MainWindow::on_fileTextEdit_undoAvailable(bool b)
{
if(b) ui->undoButton->setEnabled(true);
else ui->undoButton->setEnabled(false);
}
void MainWindow::on_fileTextEdit_redoAvailable(bool b)
{
if(b) ui->redoButton->setEnabled(true);
else ui->redoButton->setEnabled(false);
}

88
Spherebot_UI/mainwindow.h Normal file
View File

@@ -0,0 +1,88 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "spherebot.h"
#include "qextserialenumerator.h"
#include <QListWidget>
#include <QListWidgetItem>
#include <QMessageBox>
#include <QFileDialog>
#include <QTimer>
#include "txthread.h"
#include <QScrollBar>
#include <QTextCursor>
#include <QSettings>
#define DEFAULTDIAMETER 20
#define DEFAULTPENUP 35
#define DEFAULTFEEDRATE 2000
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
void send_data();
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void receivedLine(QString);
public slots:
void receiveData();
void sendData(QString data);
void finishedTransmission();
void refreshSendProgress(int value);
private slots:
void on_connectButton_clicked();
void resetPortList();
void on_sendButton_clicked();
void on_resetButton_clicked();
void on_sendString_editingFinished();
void on_servoSlider_sliderMoved(int position);
void on_servospinBox_valueChanged(int arg1);
void on_penSlider_valueChanged(int value);
void on_eggSlider_valueChanged(int value);
void on_penRotationBox_valueChanged(int arg1);
void on_eggRotationBox_valueChanged(int arg1);
void on_loadFileButton_clicked();
void on_saveFileButton_clicked();
void on_fileTextEdit_textChanged();
void on_sendFileButton_clicked();
void on_servoFeedrateSlider_valueChanged(int value);
void on_setDiameterButton_clicked();
void on_undoButton_clicked();
void on_redoButton_clicked();
void on_fileTextEdit_undoAvailable(bool b);
void on_fileTextEdit_redoAvailable(bool b);
void on_restartButton_clicked();
private:
void loadFile(const QString &fileName);
bool saveFile(const QString &fileName);
void setCurrentFile(const QString &fileName);
QString curFile;
int sendState;
QString nameSettingsFile;
Ui::MainWindow *ui;
QextSerialEnumerator serialEnumerator;
QList<QextPortInfo> portList;
spherebot bot;
QTimer *rxTimer;
txThread Transceiver;
};
#endif // MAINWINDOW_H

826
Spherebot_UI/mainwindow.ui Normal file
View File

@@ -0,0 +1,826 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1427</width>
<height>497</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QGroupBox" name="controllBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>551</width>
<height>231</height>
</rect>
</property>
<property name="title">
<string/>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>8</x>
<y>0</y>
<width>541</width>
<height>221</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<layout class="QVBoxLayout" name="verticalLayout_15">
<item>
<widget class="QPushButton" name="setDiameterButton">
<property name="text">
<string>set Diameter</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="diameterSlider">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>120</number>
</property>
<property name="value">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QSpinBox" name="diameterpinBox">
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>120</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>20</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Obj. Diameter</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_13">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="servoFeedrateSlider">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>6000</number>
</property>
<property name="value">
<number>2000</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QSpinBox" name="FeedratespinBox">
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>6000</number>
</property>
<property name="value">
<number>2000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Feedrate</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<spacer name="verticalSpacer_7">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="servoSlider">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="minimum">
<number>23</number>
</property>
<property name="maximum">
<number>120</number>
</property>
<property name="value">
<number>35</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="invertedAppearance">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_8">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QSpinBox" name="servospinBox">
<property name="minimum">
<number>23</number>
</property>
<property name="value">
<number>35</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Servo</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QSlider" name="penSlider">
<property name="minimum">
<number>-112</number>
</property>
<property name="maximum">
<number>112</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>0</number>
</property>
<property name="sliderPosition">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="penslider">
<property name="text">
<string>Pen Rotation</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="penRotationBox">
<property name="minimum">
<number>-112</number>
</property>
<property name="maximum">
<number>112</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QSlider" name="eggSlider">
<property name="minimum">
<number>-450</number>
</property>
<property name="maximum">
<number>450</number>
</property>
<property name="value">
<number>0</number>
</property>
<property name="sliderPosition">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="penslider_2">
<property name="text">
<string>Egg Rotation</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="eggRotationBox">
<property name="minimum">
<number>-450</number>
</property>
<property name="maximum">
<number>450</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>275</width>
<height>30</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="connectButton">
<property name="text">
<string>Connect</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="portBox"/>
</item>
<item>
<widget class="QPushButton" name="resetButton">
<property name="text">
<string>R</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>2</width>
<height>2</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9"/>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>2</width>
<height>2</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10"/>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>290</y>
<width>541</width>
<height>155</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="sendString"/>
</item>
<item>
<widget class="QPushButton" name="sendButton">
<property name="text">
<string>Send</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Tranceived Data</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="txList">
<property name="autoScroll">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Received Data</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="rxList"/>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>570</x>
<y>10</y>
<width>461</width>
<height>431</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8"/>
</item>
<item>
<widget class="QLabel" name="fileName">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QPushButton" name="undoButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Undo</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="redoButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Redo</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTextEdit" name="fileTextEdit"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QPushButton" name="loadFileButton">
<property name="text">
<string>Load File</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveFileButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Save File</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="sendFileButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Send File</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="restartButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Restart</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QProgressBar" name="fileSendProgressBar">
<property name="enabled">
<bool>false</bool>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QTextEdit" name="outputText">
<property name="geometry">
<rect>
<x>1040</x>
<y>80</y>
<width>351</width>
<height>291</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>1040</x>
<y>60</y>
<width>101</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Output File</string>
</property>
</widget>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections>
<connection>
<sender>diameterSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>diameterpinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>61</x>
<y>178</y>
</hint>
<hint type="destinationlabel">
<x>71</x>
<y>249</y>
</hint>
</hints>
</connection>
<connection>
<sender>diameterpinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>diameterSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>91</x>
<y>245</y>
</hint>
<hint type="destinationlabel">
<x>66</x>
<y>149</y>
</hint>
</hints>
</connection>
<connection>
<sender>servospinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>servoSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>300</x>
<y>269</y>
</hint>
<hint type="destinationlabel">
<x>272</x>
<y>237</y>
</hint>
</hints>
</connection>
<connection>
<sender>servoSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>servospinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>272</x>
<y>179</y>
</hint>
<hint type="destinationlabel">
<x>300</x>
<y>269</y>
</hint>
</hints>
</connection>
<connection>
<sender>penRotationBox</sender>
<signal>valueChanged(int)</signal>
<receiver>penSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>553</x>
<y>146</y>
</hint>
<hint type="destinationlabel">
<x>554</x>
<y>96</y>
</hint>
</hints>
</connection>
<connection>
<sender>penSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>penRotationBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>554</x>
<y>96</y>
</hint>
<hint type="destinationlabel">
<x>498</x>
<y>143</y>
</hint>
</hints>
</connection>
<connection>
<sender>eggRotationBox</sender>
<signal>valueChanged(int)</signal>
<receiver>eggSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>482</x>
<y>249</y>
</hint>
<hint type="destinationlabel">
<x>500</x>
<y>193</y>
</hint>
</hints>
</connection>
<connection>
<sender>eggSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>eggRotationBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>555</x>
<y>193</y>
</hint>
<hint type="destinationlabel">
<x>499</x>
<y>245</y>
</hint>
</hints>
</connection>
<connection>
<sender>servoFeedrateSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>FeedratespinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>178</x>
<y>228</y>
</hint>
<hint type="destinationlabel">
<x>206</x>
<y>269</y>
</hint>
</hints>
</connection>
<connection>
<sender>FeedratespinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>servoFeedrateSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>206</x>
<y>269</y>
</hint>
<hint type="destinationlabel">
<x>178</x>
<y>184</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,66 @@
#include "spherebot.h"
spherebot::spherebot(QObject *parent) :
QObject(parent)
{
port = NULL;
port_connected = false;
}
bool spherebot::connectWithBot(QString portName)
{
port = new QextSerialPort(portName , QextSerialPort::Polling); //we create the port
port->open(QIODevice::ReadWrite); //we open the port
if(!port->isOpen())
{
//QMessageBox::warning(this, "port error", "Impossible to open the port!");
return 0;
}
//we set the port properties
port->setBaudRate(BAUD115200);//modify the port settings on your own
port->setFlowControl(FLOW_OFF);
port->setParity(PAR_NONE);
port->setDataBits(DATA_8);
port->setStopBits(STOP_1);
port->setRts( true );
port->setDtr( true );
//port->setQueryMode( QextSerialPort::EventDriven );
port_connected = true;
return 1;
}
bool spherebot::disconnectWithBot()
{
qDebug("port closed");
port->close();
port_connected = false;
return 1;
}
bool spherebot::send(QString cmd)
{
if(port->isOpen())
{
port->flush();
if(cmd[cmd.size()-1] != '\n') cmd.append("\n");
qDebug()<<"Sending: " + cmd;
port->write((const char*)cmd.toUtf8(),cmd.length());
}
else
{
qDebug()<<port->errorString();
return false;
}
cmd.chop(1);
emit dataSent(cmd);
return true;
}
bool spherebot::isConnected()
{
return port_connected;
}

29
Spherebot_UI/spherebot.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef SPHEREBOT_H
#define SPHEREBOT_H
#include <QObject>
#include <qextserialport.h>
#include <QString>
#include <QtGui>
#include <iostream>
#include <QtCore/QCoreApplication>
class spherebot : public QObject
{
Q_OBJECT
public:
QextSerialPort *port;
bool isConnected();
bool send(QString cmd);
explicit spherebot(QObject *parent = 0);
signals:
void dataSent(QString data);
public slots:
bool connectWithBot(QString portName);
bool disconnectWithBot();
private:
bool port_connected;
};
#endif // SPHEREBOT_H

View File

@@ -0,0 +1,4 @@
// This file is autogenerated by qmake. It imports static plugin classes for
// static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS.<plugin> variables.
#include <QtPlugin>
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)

100
Spherebot_UI/txthread.cpp Normal file
View File

@@ -0,0 +1,100 @@
#include "txthread.h"
txThread::txThread()
{
lineCounter = 0;
bufferCounter = 0;
checkSendBufferTimer = new QTimer(this);
connect(checkSendBufferTimer,SIGNAL(timeout()),this,SLOT(checkBuffer()));
}
txThread::~txThread()
{
}
QString removeComments(QString intext)
{
////////////////////////////////////////////////remove comments
QString outTmp1,outTmp2;
bool state=1; //1= send, 0 = ignore
for(int i=0;i<intext.size();i++)
{
if(intext.at(i) == '(' ) state=0;
if(state == 1) outTmp1.append(intext[i]);
if(intext.at(i) == ')' ) state=1;
}
//////////////////////////////////////////////////remove empty lines
for(int i=0;i<outTmp1.size();i++)
{
if(i != outTmp1.size())
{
if(outTmp1[i] == '\n' && outTmp1[i+1] == '\n') i++;
else outTmp2.append(outTmp1[i]);
}
}
///////////////////////////////////////////////////
return outTmp2;
}
void txThread::set(QString intextfile,spherebot &uibot)
{
lineCounter = 0;
bufferCounter = 0;
textfile.clear();
textfile.append(removeComments(intextfile));
qDebug()<<"The textfile String is: \n\n" + textfile + "\n\nENDE\n\n";
lineMax = textfile.count("\n");
bot = &uibot;
}
void txThread::run()
{
qDebug()<<"entering run";
lineCounter = 0;
bufferCounter = 0;
drawCounter = 0;
checkSendBufferTimer->start(SENDBUFFERINTERVAL);
}
void txThread::checkBuffer()
{
//qDebug()<<"buffer check timer timeout";
if(lineCounter <= lineMax)
{
//qDebug()<<"linecounter: " + QString::number(lineCounter);
qDebug()<<"buffercounter: " + QString::number(bufferCounter);
//qDebug()<<"drawcounter: " + QString::number(drawCounter);
if(bufferCounter <= MAXBUFFERCOUNTER)
{
QString tmp = textfile.section("\n",lineCounter,lineCounter);
tmp.append("\n");
bot->send(tmp);
double progress= (double) lineCounter/(double)lineMax;
emit progressChanged(progress*100);
bufferCounter++;
lineCounter++;
}
}
else
{
checkSendBufferTimer->stop();
emit fileTransmitted();
}
}
int txThread::getLineCounter()
{
return lineCounter;
}
void txThread::checkResponse(QString msg)
{
// if(msg.count("G") > 1 || msg.count("M") > 1)
if(msg.contains("ok"))
{
qDebug()<<"processed: " + msg + "\n";
drawCounter++;
bufferCounter--;
}
}

39
Spherebot_UI/txthread.h Normal file
View File

@@ -0,0 +1,39 @@
#ifndef TXTHREAD_H
#define TXTHREAD_H
#include <QThread>
#include <QString>
#include "spherebot.h"
#include <QMessageBox>
#include <QTimer>
#define MAXBUFFERCOUNTER 1
#define SENDBUFFERINTERVAL 30
class txThread : public QThread
{
Q_OBJECT
public:
txThread();
void set(QString textfile,spherebot &bot);
void run();
~txThread();
int getLineCounter();
QTimer *checkSendBufferTimer;
signals:
void progressChanged(int);
void fileTransmitted();
public slots:
void checkResponse(QString msg);
void checkBuffer();
private:
QString textfile;
int lineCounter;
int lineMax;
int bufferCounter;
int drawCounter;
spherebot *bot;
};
#endif // TXTHREAD_H

View File

@@ -0,0 +1,627 @@
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.0.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QFrame>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QListWidget>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QProgressBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSlider>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralWidget;
QGroupBox *controllBox;
QWidget *layoutWidget;
QHBoxLayout *horizontalLayout_6;
QVBoxLayout *verticalLayout_15;
QPushButton *setDiameterButton;
QHBoxLayout *horizontalLayout_9;
QSpacerItem *verticalSpacer;
QSlider *diameterSlider;
QSpacerItem *verticalSpacer_2;
QVBoxLayout *verticalLayout_7;
QSpinBox *diameterpinBox;
QLabel *label_4;
QFrame *line_2;
QVBoxLayout *verticalLayout_13;
QHBoxLayout *horizontalLayout_11;
QSpacerItem *verticalSpacer_5;
QSlider *servoFeedrateSlider;
QSpacerItem *verticalSpacer_6;
QSpinBox *FeedratespinBox;
QLabel *label_5;
QFrame *line;
QVBoxLayout *verticalLayout_3;
QHBoxLayout *horizontalLayout_12;
QSpacerItem *verticalSpacer_7;
QSlider *servoSlider;
QSpacerItem *verticalSpacer_8;
QSpinBox *servospinBox;
QLabel *label;
QVBoxLayout *verticalLayout_6;
QVBoxLayout *verticalLayout_5;
QVBoxLayout *verticalLayout_4;
QSlider *penSlider;
QHBoxLayout *horizontalLayout_5;
QLabel *penslider;
QSpinBox *penRotationBox;
QSlider *eggSlider;
QHBoxLayout *horizontalLayout_4;
QLabel *penslider_2;
QSpinBox *eggRotationBox;
QWidget *layoutWidget1;
QHBoxLayout *horizontalLayout;
QPushButton *connectButton;
QComboBox *portBox;
QPushButton *resetButton;
QWidget *layoutWidget2;
QVBoxLayout *verticalLayout_9;
QWidget *layoutWidget3;
QVBoxLayout *verticalLayout_10;
QWidget *layoutWidget4;
QVBoxLayout *verticalLayout_11;
QHBoxLayout *horizontalLayout_3;
QLineEdit *sendString;
QPushButton *sendButton;
QHBoxLayout *horizontalLayout_2;
QVBoxLayout *verticalLayout;
QLabel *label_2;
QListWidget *txList;
QVBoxLayout *verticalLayout_2;
QLabel *label_3;
QListWidget *rxList;
QWidget *layoutWidget5;
QVBoxLayout *verticalLayout_12;
QVBoxLayout *verticalLayout_8;
QHBoxLayout *horizontalLayout_8;
QLabel *fileName;
QHBoxLayout *horizontalLayout_10;
QPushButton *undoButton;
QPushButton *redoButton;
QTextEdit *fileTextEdit;
QHBoxLayout *horizontalLayout_7;
QPushButton *loadFileButton;
QPushButton *saveFileButton;
QPushButton *sendFileButton;
QPushButton *restartButton;
QProgressBar *fileSendProgressBar;
QTextEdit *outputText;
QLabel *label_6;
QToolBar *mainToolBar;
QStatusBar *statusBar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QStringLiteral("MainWindow"));
MainWindow->resize(1427, 497);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QStringLiteral("centralWidget"));
controllBox = new QGroupBox(centralWidget);
controllBox->setObjectName(QStringLiteral("controllBox"));
controllBox->setEnabled(false);
controllBox->setGeometry(QRect(10, 60, 551, 231));
controllBox->setCheckable(false);
controllBox->setChecked(false);
layoutWidget = new QWidget(controllBox);
layoutWidget->setObjectName(QStringLiteral("layoutWidget"));
layoutWidget->setGeometry(QRect(8, 0, 541, 221));
horizontalLayout_6 = new QHBoxLayout(layoutWidget);
horizontalLayout_6->setSpacing(6);
horizontalLayout_6->setContentsMargins(11, 11, 11, 11);
horizontalLayout_6->setObjectName(QStringLiteral("horizontalLayout_6"));
horizontalLayout_6->setContentsMargins(0, 0, 0, 0);
verticalLayout_15 = new QVBoxLayout();
verticalLayout_15->setSpacing(6);
verticalLayout_15->setObjectName(QStringLiteral("verticalLayout_15"));
setDiameterButton = new QPushButton(layoutWidget);
setDiameterButton->setObjectName(QStringLiteral("setDiameterButton"));
verticalLayout_15->addWidget(setDiameterButton);
horizontalLayout_9 = new QHBoxLayout();
horizontalLayout_9->setSpacing(6);
horizontalLayout_9->setObjectName(QStringLiteral("horizontalLayout_9"));
verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
horizontalLayout_9->addItem(verticalSpacer);
diameterSlider = new QSlider(layoutWidget);
diameterSlider->setObjectName(QStringLiteral("diameterSlider"));
diameterSlider->setLayoutDirection(Qt::LeftToRight);
diameterSlider->setMinimum(5);
diameterSlider->setMaximum(120);
diameterSlider->setValue(20);
diameterSlider->setOrientation(Qt::Vertical);
diameterSlider->setInvertedAppearance(false);
horizontalLayout_9->addWidget(diameterSlider);
verticalSpacer_2 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
horizontalLayout_9->addItem(verticalSpacer_2);
verticalLayout_15->addLayout(horizontalLayout_9);
verticalLayout_7 = new QVBoxLayout();
verticalLayout_7->setSpacing(6);
verticalLayout_7->setObjectName(QStringLiteral("verticalLayout_7"));
diameterpinBox = new QSpinBox(layoutWidget);
diameterpinBox->setObjectName(QStringLiteral("diameterpinBox"));
diameterpinBox->setMinimum(5);
diameterpinBox->setMaximum(120);
diameterpinBox->setSingleStep(1);
diameterpinBox->setValue(20);
verticalLayout_7->addWidget(diameterpinBox);
label_4 = new QLabel(layoutWidget);
label_4->setObjectName(QStringLiteral("label_4"));
verticalLayout_7->addWidget(label_4);
verticalLayout_15->addLayout(verticalLayout_7);
horizontalLayout_6->addLayout(verticalLayout_15);
line_2 = new QFrame(layoutWidget);
line_2->setObjectName(QStringLiteral("line_2"));
line_2->setFrameShape(QFrame::VLine);
line_2->setFrameShadow(QFrame::Sunken);
horizontalLayout_6->addWidget(line_2);
verticalLayout_13 = new QVBoxLayout();
verticalLayout_13->setSpacing(6);
verticalLayout_13->setObjectName(QStringLiteral("verticalLayout_13"));
horizontalLayout_11 = new QHBoxLayout();
horizontalLayout_11->setSpacing(6);
horizontalLayout_11->setObjectName(QStringLiteral("horizontalLayout_11"));
verticalSpacer_5 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
horizontalLayout_11->addItem(verticalSpacer_5);
servoFeedrateSlider = new QSlider(layoutWidget);
servoFeedrateSlider->setObjectName(QStringLiteral("servoFeedrateSlider"));
servoFeedrateSlider->setLayoutDirection(Qt::LeftToRight);
servoFeedrateSlider->setMinimum(10);
servoFeedrateSlider->setMaximum(6000);
servoFeedrateSlider->setValue(2000);
servoFeedrateSlider->setOrientation(Qt::Vertical);
servoFeedrateSlider->setInvertedAppearance(false);
horizontalLayout_11->addWidget(servoFeedrateSlider);
verticalSpacer_6 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
horizontalLayout_11->addItem(verticalSpacer_6);
verticalLayout_13->addLayout(horizontalLayout_11);
FeedratespinBox = new QSpinBox(layoutWidget);
FeedratespinBox->setObjectName(QStringLiteral("FeedratespinBox"));
FeedratespinBox->setMinimum(10);
FeedratespinBox->setMaximum(6000);
FeedratespinBox->setValue(2000);
verticalLayout_13->addWidget(FeedratespinBox);
label_5 = new QLabel(layoutWidget);
label_5->setObjectName(QStringLiteral("label_5"));
verticalLayout_13->addWidget(label_5);
horizontalLayout_6->addLayout(verticalLayout_13);
line = new QFrame(layoutWidget);
line->setObjectName(QStringLiteral("line"));
line->setFrameShape(QFrame::VLine);
line->setFrameShadow(QFrame::Sunken);
horizontalLayout_6->addWidget(line);
verticalLayout_3 = new QVBoxLayout();
verticalLayout_3->setSpacing(6);
verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3"));
horizontalLayout_12 = new QHBoxLayout();
horizontalLayout_12->setSpacing(6);
horizontalLayout_12->setObjectName(QStringLiteral("horizontalLayout_12"));
verticalSpacer_7 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
horizontalLayout_12->addItem(verticalSpacer_7);
servoSlider = new QSlider(layoutWidget);
servoSlider->setObjectName(QStringLiteral("servoSlider"));
servoSlider->setLayoutDirection(Qt::LeftToRight);
servoSlider->setMinimum(23);
servoSlider->setMaximum(120);
servoSlider->setValue(35);
servoSlider->setOrientation(Qt::Vertical);
servoSlider->setInvertedAppearance(true);
horizontalLayout_12->addWidget(servoSlider);
verticalSpacer_8 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
horizontalLayout_12->addItem(verticalSpacer_8);
verticalLayout_3->addLayout(horizontalLayout_12);
servospinBox = new QSpinBox(layoutWidget);
servospinBox->setObjectName(QStringLiteral("servospinBox"));
servospinBox->setMinimum(23);
servospinBox->setValue(35);
verticalLayout_3->addWidget(servospinBox);
label = new QLabel(layoutWidget);
label->setObjectName(QStringLiteral("label"));
verticalLayout_3->addWidget(label);
horizontalLayout_6->addLayout(verticalLayout_3);
verticalLayout_6 = new QVBoxLayout();
verticalLayout_6->setSpacing(6);
verticalLayout_6->setObjectName(QStringLiteral("verticalLayout_6"));
verticalLayout_5 = new QVBoxLayout();
verticalLayout_5->setSpacing(6);
verticalLayout_5->setObjectName(QStringLiteral("verticalLayout_5"));
verticalLayout_4 = new QVBoxLayout();
verticalLayout_4->setSpacing(6);
verticalLayout_4->setObjectName(QStringLiteral("verticalLayout_4"));
penSlider = new QSlider(layoutWidget);
penSlider->setObjectName(QStringLiteral("penSlider"));
penSlider->setMinimum(-112);
penSlider->setMaximum(112);
penSlider->setSingleStep(1);
penSlider->setValue(0);
penSlider->setSliderPosition(0);
penSlider->setOrientation(Qt::Horizontal);
penSlider->setInvertedAppearance(true);
verticalLayout_4->addWidget(penSlider);
horizontalLayout_5 = new QHBoxLayout();
horizontalLayout_5->setSpacing(6);
horizontalLayout_5->setObjectName(QStringLiteral("horizontalLayout_5"));
penslider = new QLabel(layoutWidget);
penslider->setObjectName(QStringLiteral("penslider"));
horizontalLayout_5->addWidget(penslider);
penRotationBox = new QSpinBox(layoutWidget);
penRotationBox->setObjectName(QStringLiteral("penRotationBox"));
penRotationBox->setMinimum(-112);
penRotationBox->setMaximum(112);
penRotationBox->setSingleStep(1);
horizontalLayout_5->addWidget(penRotationBox);
verticalLayout_4->addLayout(horizontalLayout_5);
verticalLayout_5->addLayout(verticalLayout_4);
eggSlider = new QSlider(layoutWidget);
eggSlider->setObjectName(QStringLiteral("eggSlider"));
eggSlider->setMinimum(-450);
eggSlider->setMaximum(450);
eggSlider->setValue(0);
eggSlider->setSliderPosition(0);
eggSlider->setOrientation(Qt::Horizontal);
verticalLayout_5->addWidget(eggSlider);
horizontalLayout_4 = new QHBoxLayout();
horizontalLayout_4->setSpacing(6);
horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4"));
penslider_2 = new QLabel(layoutWidget);
penslider_2->setObjectName(QStringLiteral("penslider_2"));
horizontalLayout_4->addWidget(penslider_2);
eggRotationBox = new QSpinBox(layoutWidget);
eggRotationBox->setObjectName(QStringLiteral("eggRotationBox"));
eggRotationBox->setMinimum(-450);
eggRotationBox->setMaximum(450);
horizontalLayout_4->addWidget(eggRotationBox);
verticalLayout_5->addLayout(horizontalLayout_4);
verticalLayout_6->addLayout(verticalLayout_5);
horizontalLayout_6->addLayout(verticalLayout_6);
layoutWidget1 = new QWidget(centralWidget);
layoutWidget1->setObjectName(QStringLiteral("layoutWidget1"));
layoutWidget1->setGeometry(QRect(20, 20, 275, 30));
horizontalLayout = new QHBoxLayout(layoutWidget1);
horizontalLayout->setSpacing(6);
horizontalLayout->setContentsMargins(11, 11, 11, 11);
horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
horizontalLayout->setContentsMargins(0, 0, 0, 0);
connectButton = new QPushButton(layoutWidget1);
connectButton->setObjectName(QStringLiteral("connectButton"));
connectButton->setCheckable(false);
horizontalLayout->addWidget(connectButton);
portBox = new QComboBox(layoutWidget1);
portBox->setObjectName(QStringLiteral("portBox"));
horizontalLayout->addWidget(portBox);
resetButton = new QPushButton(layoutWidget1);
resetButton->setObjectName(QStringLiteral("resetButton"));
horizontalLayout->addWidget(resetButton);
layoutWidget2 = new QWidget(centralWidget);
layoutWidget2->setObjectName(QStringLiteral("layoutWidget2"));
layoutWidget2->setGeometry(QRect(0, 0, 2, 2));
verticalLayout_9 = new QVBoxLayout(layoutWidget2);
verticalLayout_9->setSpacing(6);
verticalLayout_9->setContentsMargins(11, 11, 11, 11);
verticalLayout_9->setObjectName(QStringLiteral("verticalLayout_9"));
verticalLayout_9->setContentsMargins(0, 0, 0, 0);
layoutWidget3 = new QWidget(centralWidget);
layoutWidget3->setObjectName(QStringLiteral("layoutWidget3"));
layoutWidget3->setGeometry(QRect(0, 0, 2, 2));
verticalLayout_10 = new QVBoxLayout(layoutWidget3);
verticalLayout_10->setSpacing(6);
verticalLayout_10->setContentsMargins(11, 11, 11, 11);
verticalLayout_10->setObjectName(QStringLiteral("verticalLayout_10"));
verticalLayout_10->setContentsMargins(0, 0, 0, 0);
layoutWidget4 = new QWidget(centralWidget);
layoutWidget4->setObjectName(QStringLiteral("layoutWidget4"));
layoutWidget4->setGeometry(QRect(20, 290, 541, 155));
verticalLayout_11 = new QVBoxLayout(layoutWidget4);
verticalLayout_11->setSpacing(6);
verticalLayout_11->setContentsMargins(11, 11, 11, 11);
verticalLayout_11->setObjectName(QStringLiteral("verticalLayout_11"));
verticalLayout_11->setContentsMargins(0, 0, 0, 0);
horizontalLayout_3 = new QHBoxLayout();
horizontalLayout_3->setSpacing(6);
horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3"));
sendString = new QLineEdit(layoutWidget4);
sendString->setObjectName(QStringLiteral("sendString"));
horizontalLayout_3->addWidget(sendString);
sendButton = new QPushButton(layoutWidget4);
sendButton->setObjectName(QStringLiteral("sendButton"));
horizontalLayout_3->addWidget(sendButton);
verticalLayout_11->addLayout(horizontalLayout_3);
horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setSpacing(6);
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
verticalLayout = new QVBoxLayout();
verticalLayout->setSpacing(6);
verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
label_2 = new QLabel(layoutWidget4);
label_2->setObjectName(QStringLiteral("label_2"));
verticalLayout->addWidget(label_2);
txList = new QListWidget(layoutWidget4);
txList->setObjectName(QStringLiteral("txList"));
txList->setAutoScroll(false);
txList->setSelectionMode(QAbstractItemView::NoSelection);
verticalLayout->addWidget(txList);
horizontalLayout_2->addLayout(verticalLayout);
verticalLayout_2 = new QVBoxLayout();
verticalLayout_2->setSpacing(6);
verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2"));
label_3 = new QLabel(layoutWidget4);
label_3->setObjectName(QStringLiteral("label_3"));
verticalLayout_2->addWidget(label_3);
rxList = new QListWidget(layoutWidget4);
rxList->setObjectName(QStringLiteral("rxList"));
verticalLayout_2->addWidget(rxList);
horizontalLayout_2->addLayout(verticalLayout_2);
verticalLayout_11->addLayout(horizontalLayout_2);
layoutWidget5 = new QWidget(centralWidget);
layoutWidget5->setObjectName(QStringLiteral("layoutWidget5"));
layoutWidget5->setGeometry(QRect(570, 10, 461, 431));
verticalLayout_12 = new QVBoxLayout(layoutWidget5);
verticalLayout_12->setSpacing(6);
verticalLayout_12->setContentsMargins(11, 11, 11, 11);
verticalLayout_12->setObjectName(QStringLiteral("verticalLayout_12"));
verticalLayout_12->setContentsMargins(0, 0, 0, 0);
verticalLayout_8 = new QVBoxLayout();
verticalLayout_8->setSpacing(6);
verticalLayout_8->setObjectName(QStringLiteral("verticalLayout_8"));
horizontalLayout_8 = new QHBoxLayout();
horizontalLayout_8->setSpacing(6);
horizontalLayout_8->setObjectName(QStringLiteral("horizontalLayout_8"));
verticalLayout_8->addLayout(horizontalLayout_8);
fileName = new QLabel(layoutWidget5);
fileName->setObjectName(QStringLiteral("fileName"));
verticalLayout_8->addWidget(fileName);
horizontalLayout_10 = new QHBoxLayout();
horizontalLayout_10->setSpacing(6);
horizontalLayout_10->setObjectName(QStringLiteral("horizontalLayout_10"));
undoButton = new QPushButton(layoutWidget5);
undoButton->setObjectName(QStringLiteral("undoButton"));
undoButton->setEnabled(false);
horizontalLayout_10->addWidget(undoButton);
redoButton = new QPushButton(layoutWidget5);
redoButton->setObjectName(QStringLiteral("redoButton"));
redoButton->setEnabled(false);
horizontalLayout_10->addWidget(redoButton);
verticalLayout_8->addLayout(horizontalLayout_10);
fileTextEdit = new QTextEdit(layoutWidget5);
fileTextEdit->setObjectName(QStringLiteral("fileTextEdit"));
verticalLayout_8->addWidget(fileTextEdit);
horizontalLayout_7 = new QHBoxLayout();
horizontalLayout_7->setSpacing(6);
horizontalLayout_7->setObjectName(QStringLiteral("horizontalLayout_7"));
loadFileButton = new QPushButton(layoutWidget5);
loadFileButton->setObjectName(QStringLiteral("loadFileButton"));
horizontalLayout_7->addWidget(loadFileButton);
saveFileButton = new QPushButton(layoutWidget5);
saveFileButton->setObjectName(QStringLiteral("saveFileButton"));
saveFileButton->setEnabled(false);
horizontalLayout_7->addWidget(saveFileButton);
sendFileButton = new QPushButton(layoutWidget5);
sendFileButton->setObjectName(QStringLiteral("sendFileButton"));
sendFileButton->setEnabled(false);
horizontalLayout_7->addWidget(sendFileButton);
restartButton = new QPushButton(layoutWidget5);
restartButton->setObjectName(QStringLiteral("restartButton"));
restartButton->setEnabled(false);
horizontalLayout_7->addWidget(restartButton);
verticalLayout_8->addLayout(horizontalLayout_7);
verticalLayout_12->addLayout(verticalLayout_8);
fileSendProgressBar = new QProgressBar(layoutWidget5);
fileSendProgressBar->setObjectName(QStringLiteral("fileSendProgressBar"));
fileSendProgressBar->setEnabled(false);
fileSendProgressBar->setValue(0);
verticalLayout_12->addWidget(fileSendProgressBar);
outputText = new QTextEdit(centralWidget);
outputText->setObjectName(QStringLiteral("outputText"));
outputText->setGeometry(QRect(1040, 80, 351, 291));
label_6 = new QLabel(centralWidget);
label_6->setObjectName(QStringLiteral("label_6"));
label_6->setGeometry(QRect(1040, 60, 101, 16));
MainWindow->setCentralWidget(centralWidget);
mainToolBar = new QToolBar(MainWindow);
mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(MainWindow);
statusBar->setObjectName(QStringLiteral("statusBar"));
MainWindow->setStatusBar(statusBar);
retranslateUi(MainWindow);
QObject::connect(diameterSlider, SIGNAL(valueChanged(int)), diameterpinBox, SLOT(setValue(int)));
QObject::connect(diameterpinBox, SIGNAL(valueChanged(int)), diameterSlider, SLOT(setValue(int)));
QObject::connect(servospinBox, SIGNAL(valueChanged(int)), servoSlider, SLOT(setValue(int)));
QObject::connect(servoSlider, SIGNAL(valueChanged(int)), servospinBox, SLOT(setValue(int)));
QObject::connect(penRotationBox, SIGNAL(valueChanged(int)), penSlider, SLOT(setValue(int)));
QObject::connect(penSlider, SIGNAL(valueChanged(int)), penRotationBox, SLOT(setValue(int)));
QObject::connect(eggRotationBox, SIGNAL(valueChanged(int)), eggSlider, SLOT(setValue(int)));
QObject::connect(eggSlider, SIGNAL(valueChanged(int)), eggRotationBox, SLOT(setValue(int)));
QObject::connect(servoFeedrateSlider, SIGNAL(valueChanged(int)), FeedratespinBox, SLOT(setValue(int)));
QObject::connect(FeedratespinBox, SIGNAL(valueChanged(int)), servoFeedrateSlider, SLOT(setValue(int)));
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0));
controllBox->setTitle(QString());
setDiameterButton->setText(QApplication::translate("MainWindow", "set Diameter", 0));
label_4->setText(QApplication::translate("MainWindow", "Obj. Diameter", 0));
label_5->setText(QApplication::translate("MainWindow", "Feedrate", 0));
label->setText(QApplication::translate("MainWindow", "Servo", 0));
penslider->setText(QApplication::translate("MainWindow", "Pen Rotation", 0));
penslider_2->setText(QApplication::translate("MainWindow", "Egg Rotation", 0));
connectButton->setText(QApplication::translate("MainWindow", "Connect", 0));
resetButton->setText(QApplication::translate("MainWindow", "R", 0));
sendButton->setText(QApplication::translate("MainWindow", "Send", 0));
label_2->setText(QApplication::translate("MainWindow", "Tranceived Data", 0));
label_3->setText(QApplication::translate("MainWindow", "Received Data", 0));
fileName->setText(QString());
undoButton->setText(QApplication::translate("MainWindow", "Undo", 0));
redoButton->setText(QApplication::translate("MainWindow", "Redo", 0));
loadFileButton->setText(QApplication::translate("MainWindow", "Load File", 0));
saveFileButton->setText(QApplication::translate("MainWindow", "Save File", 0));
sendFileButton->setText(QApplication::translate("MainWindow", "Send File", 0));
restartButton->setText(QApplication::translate("MainWindow", "Restart", 0));
label_6->setText(QApplication::translate("MainWindow", "Output File", 0));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H