Ex1.
Determination of Maximum and Minimum Position of Links
Ex2. Verification of Transformation (Position & Orientation) with respect to Gripper
and World Coordinate System
Ex3. Estimation of Accuracy, Repeatability, and Resolution
Ex4. Robot Programming and Simulation for Pick and Place
#include <Servo.h> // Include the Servo library
Servo baseServo; // Servo for the base rotation
Servo armServo1; // Servo for the lower arm joint
Servo armServo2; // Servo for the upper arm joint
Servo gripperServo; // Servo for the gripper
void setup() {
[Link](9600); // Initialize serial communication for debugging
// Attach servos to their respective pins
[Link](9); // Example pin 9
[Link](10); // Example pin 10
[Link](11); // Example pin 11
[Link](12); // Example pin 12
// Set initial positions (adjust as needed for your specific arm)
[Link](90);
[Link](90);
[Link](90);
[Link](0); // Gripper open
delay(1000); // Allow time for servos to reach initial position
}
void loop() {
// Example sequence for picking and placing an object
// This can be triggered by a sensor, a button, or serial input
// 1. Move to pick position
moveToPosition(90, 45, 135, 0); // Base, Arm1, Arm2, Gripper (open)
delay(2000);
// 2. Close gripper to pick up object
[Link](90); // Gripper closed
delay(1000);
// 3. Lift object
moveToPosition(90, 90, 90, 90); // Lifted position
delay(2000);
// 4. Move to place position
moveToPosition(0, 45, 135, 90); // Base, Arm1, Arm2, Gripper (closed)
delay(2000);
// 5. Open gripper to place object
[Link](0); // Gripper open
delay(1000);
// 6. Return to home/idle position
moveToPosition(90, 90, 90, 0); // Home position
delay(2000);
}
// Function to move the robotic arm to a specified set of angles
void moveToPosition(int baseAngle, int arm1Angle, int arm2Angle, int gripperAngle) {
[Link](baseAngle);
[Link](arm1Angle);
[Link](arm2Angle);
[Link](gripperAngle);
}
Ex5. Robot Programming and Simulation for Colour Identification
#include <Wire.h>
#include "Adafruit_TCS34725.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define redpin 3
#define greenpin 5
#define bluepin 6
#define commonAnode true
byte gammatable[256];
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS,
TCS34725_GAIN_4X);
void setup() {
[Link](9600);
[Link]();
[Link]();
[Link]();
if ([Link]()) {
} else {
[Link]("No TCS34725 found ... check your connections");
while (1);
}
pinMode(redpin, OUTPUT);
pinMode(greenpin, OUTPUT);
pinMode(bluepin, OUTPUT);
for (int i=0; i<256; i++) {
float x = i;
x /= 255;
x = pow(x, 2.5);
x *= 255;
if (commonAnode) {
gammatable[i] = 255 - x;
} else {
gammatable[i] = x;
}
}
}
void loop() {
float red, green, blue;
[Link](false); // turn on LED
delay(60); // takes 50ms to read
[Link](&red, &green, &blue);
[Link](true); // turn off LED
[Link]("R:\t"); [Link](int(red));
[Link]("\tG:\t"); [Link](int(green));
[Link]("\tB:\t"); [Link](int(blue));
[Link]();
[Link](4,0);
[Link]("DEMO");
[Link](3,1);
[Link]("Color");
[Link](10,1);
if(int (red)>=120){
[Link]("\n");
[Link] ("Red");
}
if(int (blue)>=110){
[Link]("\n");
[Link] ("Blue");
}
if(int (green)>=120){
[Link]("\n");
[Link] ("Green");
}
[Link]("\n");
analogWrite(redpin, gammatable[(int)red]);
analogWrite(greenpin, gammatable[(int)green]);
analogWrite(bluepin, gammatable[(int)blue]);
}
Ex6. Robot Programming and Simulation for Shape Identification
// Motor Control Pins
#define MOTOR_A1 2
#define MOTOR_A2 3
#define MOTOR_B1 4
#define MOTOR_B2 5
#define MOTOR_PWM_A 9
#define MOTOR_PWM_B 10
// Sensor Pins
#define LEFT_IR_SENSOR A0
#define RIGHT_IR_SENSOR A1
#define FRONT_IR_SENSOR A2
#define ULTRASONIC_TRIG 6
#define ULTRASONIC_ECHO 7
// Shape Detection Parameters
#define SHAPE_THRESHOLD 500
#define WALL_DISTANCE 15
#define CORNER_ANGLE 90
// Global Variables
int leftSensorValue = 0;
int rightSensorValue = 0;
int frontSensorValue = 0;
long duration, distance;
enum Shape {
UNKNOWN,
CIRCLE,
SQUARE,
TRIANGLE,
RECTANGLE
};
Shape detectedShape = UNKNOWN;
void setup() {
// Initialize motor pins
pinMode(MOTOR_A1, OUTPUT);
pinMode(MOTOR_A2, OUTPUT);
pinMode(MOTOR_B1, OUTPUT);
pinMode(MOTOR_B2, OUTPUT);
pinMode(MOTOR_PWM_A, OUTPUT);
pinMode(MOTOR_PWM_B, OUTPUT);
// Initialize sensor pins
pinMode(LEFT_IR_SENSOR, INPUT);
pinMode(RIGHT_IR_SENSOR, INPUT);
pinMode(FRONT_IR_SENSOR, INPUT);
pinMode(ULTRASONIC_TRIG, OUTPUT);
pinMode(ULTRASONIC_ECHO, INPUT);
// Initialize serial communication
[Link](9600);
[Link]("Robot Shape Identification System Started");
// Calibration delay
delay(2000);
}
void loop() {
readSensors();
detectShape();
navigate();
reportFindings();
delay(100);
}
void readSensors() {
// Read IR sensors
leftSensorValue = analogRead(LEFT_IR_SENSOR);
rightSensorValue = analogRead(RIGHT_IR_SENSOR);
frontSensorValue = analogRead(FRONT_IR_SENSOR);
// Read ultrasonic sensor
digitalWrite(ULTRASONIC_TRIG, LOW);
delayMicroseconds(2);
digitalWrite(ULTRASONIC_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(ULTRASONIC_TRIG, LOW);
duration = pulseIn(ULTRASONIC_ECHO, HIGH);
distance = duration * 0.034 / 2;
}
void detectShape() {
static int cornerCount = 0;
static unsigned long lastCornerTime = 0;
static bool trackingShape = false;
// Check if we're following a shape
if (leftSensorValue < SHAPE_THRESHOLD || rightSensorValue < SHAPE_THRESHOLD)
{
trackingShape = true;
// Detect corners based on sudden sensor value changes
if (abs(leftSensorValue - rightSensorValue) > 300) {
if (millis() - lastCornerTime > 1000) { // Debounce
cornerCount++;
lastCornerTime = millis();
[Link]("Corner detected! Total corners: ");
[Link](cornerCount);
} }
}
else if (trackingShape) {
// We've completed following a shape
identifyShapeFromCorners(cornerCount);
cornerCount = 0;
trackingShape = false;
}}
void identifyShapeFromCorners(int corners) {
switch(corners) {
case 0:
detectedShape = CIRCLE;
break;
case 3:
detectedShape = TRIANGLE;
break;
case 4:
// Differentiate between square and rectangle
if (checkAspectRatio()) {
detectedShape = SQUARE;
} else {
detectedShape = RECTANGLE;
}
break;
default:
detectedShape = UNKNOWN;
}
[Link]("Shape Identified: ");
printShapeName(detectedShape);
}
bool checkAspectRatio() {
// Simulate aspect ratio check
// In real implementation, you'd measure side lengths
return random(0, 2); // Random for simulation
}
void navigate() {
// Basic line following and obstacle avoidance
if (distance < WALL_DISTANCE) {
avoidObstacle();
} else if (frontSensorValue < SHAPE_THRESHOLD) {
followShape();
} else {
explore();
}}
void followShape() {
// Line following algorithm for shape tracking
if (leftSensorValue < SHAPE_THRESHOLD && rightSensorValue <
SHAPE_THRESHOLD)
{
moveForward();
} else if (leftSensorValue < SHAPE_THRESHOLD) {
turnLeft();
} else if (rightSensorValue < SHAPE_THRESHOLD) {
turnRight();
} else {
moveForward();
} }
void avoidObstacle() {
[Link]("Obstacle detected! Avoiding...");
moveBackward(500);
turnRight(800);
moveForward();
}
void explore() {
// Random exploration pattern
int randomAction = random(0, 4);
switch(randomAction) {
case 0:
moveForward();
break;
case 1:
turnLeft(300);
break;
case 2:
turnRight(300);
break;
case 3:
stopMotors();
delay(500);
break;
}}
// Motor Control Functions
void moveForward() {
digitalWrite(MOTOR_A1, HIGH);
digitalWrite(MOTOR_A2, LOW);
digitalWrite(MOTOR_B1, HIGH);
digitalWrite(MOTOR_B2, LOW);
analogWrite(MOTOR_PWM_A, 150);
analogWrite(MOTOR_PWM_B, 150);
}
void moveBackward(int duration = 0) {
digitalWrite(MOTOR_A1, LOW);
digitalWrite(MOTOR_A2, HIGH);
digitalWrite(MOTOR_B1, LOW);
digitalWrite(MOTOR_B2, HIGH);
analogWrite(MOTOR_PWM_A, 150);
analogWrite(MOTOR_PWM_B, 150);
if (duration > 0) {
delay(duration);
stopMotors();
}
}
void turnLeft(int duration = 0) {
digitalWrite(MOTOR_A1, LOW);
digitalWrite(MOTOR_A2, HIGH);
digitalWrite(MOTOR_B1, HIGH);
digitalWrite(MOTOR_B2, LOW);
analogWrite(MOTOR_PWM_A, 150);
analogWrite(MOTOR_PWM_B, 150);
if (duration > 0) {
delay(duration);
stopMotors();
}}
void turnRight(int duration = 0) {
digitalWrite(MOTOR_A1, HIGH);
digitalWrite(MOTOR_A2, LOW);
digitalWrite(MOTOR_B1, LOW);
digitalWrite(MOTOR_B2, HIGH);
analogWrite(MOTOR_PWM_A, 150);
analogWrite(MOTOR_PWM_B, 150);
if (duration > 0) {
delay(duration);
stopMotors();
}}
void stopMotors() {
digitalWrite(MOTOR_A1, LOW);
digitalWrite(MOTOR_A2, LOW);
digitalWrite(MOTOR_B1, LOW);
digitalWrite(MOTOR_B2, LOW);
analogWrite(MOTOR_PWM_A, 0);
analogWrite(MOTOR_PWM_B, 0);
}
void reportFindings() {
static unsigned long lastReport = 0;
if (millis() - lastReport > 5000) { // Report every 5 seconds
[Link]("=== Robot Status Report ===");
[Link]("Left Sensor: "); [Link](leftSensorValue);
[Link]("Right Sensor: "); [Link](rightSensorValue);
[Link]("Front Sensor: "); [Link](frontSensorValue);
[Link]("Distance: "); [Link](distance); [Link](" cm");
[Link]("Current Shape: "); printShapeName(detectedShape);
lastReport = millis();
}}
void printShapeName(Shape shape) {
switch(shape) {
case CIRCLE:
[Link]("CIRCLE");
break;
case SQUARE:
[Link]("SQUARE");
break;
case TRIANGLE:
[Link]("TRIANGLE");
break;
case RECTANGLE:
[Link]("RECTANGLE");
break;
default:
[Link]("UNKNOWN");
}
}
Ex7. Robot Programming and Simulation for Machining (Cutting, Welding)
1. Basic Robot Control System Architecture
// Robot Control System for Machining
#include <Stepper.h>
#include <Servo.h>
#include <EEPROM.h>
// Motor Definitions
#define STEPS_PER_REV 200
Stepper xAxis(STEPS_PER_REV, 2, 3, 4, 5);
Stepper yAxis(STEPS_PER_REV, 6, 7, 8, 9);
Stepper zAxis(STEPS_PER_REV, 10, 11, 12, 13);
// End Effector (Welding Torch/Cutting Tool)
Servo endEffector;
const int TOOL_PIN = A0;
const int TOOL_PWM = 3;
// Sensor Pins
const int LIMIT_SWITCH_X = A1;
const int LIMIT_SWITCH_Y = A2;
const int LIMIT_SWITCH_Z = A3;
const int TEMP_SENSOR = A4;
// Robot State Variables
struct RobotState {
float x, y, z;
float speed;
bool toolActive;
int toolPower;
};
RobotState currentState = {0, 0, 0, 100, false, 0};
2. Core Robot Movement Functions
class RobotController {
private:
float maxSpeed = 500; // steps/sec
float acceleration = 100; // steps/sec²
public:
void initializeRobot() {
pinMode(LIMIT_SWITCH_X, INPUT_PULLUP);
pinMode(LIMIT_SWITCH_Y, INPUT_PULLUP);
pinMode(LIMIT_SWITCH_Z, INPUT_PULLUP);
[Link](TOOL_PIN);
[Link](0);
setMotorSpeed([Link]);
homingSequence();
}
void homingSequence() {
// Move to home position using limit switches
while(digitalRead(LIMIT_SWITCH_X) == HIGH) {
[Link](-1);
delay(5);
}
while(digitalRead(LIMIT_SWITCH_Y) == HIGH) {
[Link](-1);
delay(5);
}
while(digitalRead(LIMIT_SWITCH_Z) == HIGH) {
[Link](-1);
delay(5);
}
currentState.x = 0;
currentState.y = 0;
currentState.z = 0;
}
void moveTo(float targetX, float targetY, float targetZ) {
// Calculate steps needed
long stepsX = (targetX - currentState.x) * STEPS_PER_MM;
long stepsY = (targetY - currentState.y) * STEPS_PER_MM;
long stepsZ = (targetZ - currentState.z) * STEPS_PER_MM;
// Implement coordinated movement
coordinatedMove(stepsX, stepsY, stepsZ);
// Update current position
currentState.x = targetX;
currentState.y = targetY;
currentState.z = targetZ;
}
void coordinatedMove(long dx, long dy, long dz) {
long maxSteps = max(abs(dx), max(abs(dy), abs(dz)));
for(long i = 0; i < maxSteps; i++) {
if(i < abs(dx)) [Link](dx > 0 ? 1 : -1);
if(i < abs(dy)) [Link](dy > 0 ? 1 : -1);
if(i < abs(dz)) [Link](dz > 0 ? 1 : -1);
delayMicroseconds(1000000 / [Link]);
}
}
};
3. Welding Robot Implementation
class WeldingRobot : public RobotController {
private:
int weldCurrent = 0;
int wireFeedSpeed = 0;
bool arcEstablished = false;
public:
void startWelding(int current, int wireSpeed) {
weldCurrent = current;
wireFeedSpeed = wireSpeed;
// Establish arc
establishArc();
// Start wire feed
analogWrite(TOOL_PWM, map(wireFeedSpeed, 0, 100, 0, 255));
[Link] = true;
arcEstablished = true;
}
void stopWelding() {
analogWrite(TOOL_PWM, 0);
[Link](0);
[Link] = false;
arcEstablished = false;
}
void weldingPattern(String patternType, float length) {
if(patternType == "straight") {
straightWeld(length);
} else if(patternType == "circular") {
circularWeld(length);
} else if(patternType == "zigzag") {
zigzagWeld(length);
}
}
private:
void establishArc() {
// Simulate arc establishment
for(int i = 0; i < 100; i++) {
[Link](i);
delay(10);
}
}
void straightWeld(float length) {
float startX = currentState.x;
moveTo(startX + length, currentState.y, currentState.z);
}
void circularWeld(float diameter) {
int points = 36;
float radius = diameter / 2;
float centerX = currentState.x + radius;
float centerY = currentState.y;
for(int i = 0; i <= points; i++) {
float angle = 2 * PI * i / points;
float x = centerX + radius * cos(angle);
float y = centerY + radius * sin(angle);
moveTo(x, y, currentState.z);
}
}
void zigzagWeld(float length) {
float amplitude = 5.0; // mm
int cycles = 5;
for(int i = 0; i <= cycles; i++) {
float x = currentState.x + (length * i / cycles);
float y = currentState.y + amplitude * sin(i * PI / cycles);
moveTo(x, y, currentState.z);
} } };
4. Cutting Robot Implementation
class CuttingRobot : public RobotController {
private:
int cutPower = 0;
bool plasmaActive = false;
public:
void startCutting(int power) {
cutPower = power;
plasmaActive = true;
// Activate plasma/laser
analogWrite(TOOL_PWM, map(power, 0, 100, 0, 255));
[Link](90); // Cutting position
[Link] = true;
}
void stopCutting() {
analogWrite(TOOL_PWM, 0);
[Link](0);
plasmaActive = false;
[Link] = false;
}
void cutShape(String shape, float dimension) {
if(shape == "square") {
cutSquare(dimension);
} else if(shape == "circle") {
cutCircle(dimension);
}
else if(shape == "rectangle") {
cutRectangle(dimension, dimension/2);
} }
void followPath(float* pathX, float* pathY, int points) {
startCutting(80);
for(int i = 0; i < points; i++) {
moveTo(pathX[i], pathY[i], currentState.z);
}
stopCutting();
}
private:
void cutSquare(float size) {
float startX = currentState.x;
float startY = currentState.y;
startCutting(80);
moveTo(startX + size, startY, currentState.z);
moveTo(startX + size, startY + size, currentState.z);
moveTo(startX, startY + size, currentState.z);
moveTo(startX, startY, currentState.z);
stopCutting();
}
void cutCircle(float diameter) {
startCutting(80);
circularWeld(diameter); // Reuse welding circular pattern
stopCutting();
}
void cutRectangle(float width, float height) {
float startX = currentState.x;
float startY = currentState.y;
startCutting(80);
moveTo(startX + width, startY, currentState.z);
moveTo(startX + width, startY + height, currentState.z);
moveTo(startX, startY + height, currentState.z);
moveTo(startX, startY, currentState.z);
stopCutting();
}
};
5. G-code Interpreter for Machining
class GCodeInterpreter {
private:
String commandBuffer;
public:
void processGCode(String gcode) {
[Link]();
[Link]();
if([Link]("G00")) {
// Rapid positioning
rapidMove(gcode);
} else if([Link]("G01")) {
// Linear interpolation
linearMove(gcode);
} else if([Link]("G02")) {
// Circular interpolation CW
circularMove(gcode, true);
} else if([Link]("G03")) {
// Circular interpolation CCW
circularMove(gcode, false);
} else if([Link]("M03")) {
// Spindle/Tool ON
startTool(gcode);
} else if([Link]("M05")) {
// Spindle/Tool OFF
stopTool();
}
}
private:
void rapidMove(String command) {
float x = extractCoordinate(command, 'X');
float y = extractCoordinate(command, 'Y');
float z = extractCoordinate(command, 'Z');
// Move without tool activation
moveTo(x, y, z);
}
void linearMove(String command) {
float x = extractCoordinate(command, 'X');
float y = extractCoordinate(command, 'Y');
float z = extractCoordinate(command, 'Z');
float f = extractCoordinate(command, 'F');
if(f > 0) [Link] = f;
// Move with possible tool activation
moveTo(x, y, z);
}
void circularMove(String command, bool clockwise) {
// Extract parameters for circular interpolation
float x = extractCoordinate(command, 'X');
float y = extractCoordinate(command, 'Y');
float i = extractCoordinate(command, 'I');
float j = extractCoordinate(command, 'J');
// Implement circular path
executeCircularPath(x, y, i, j, clockwise);
}
float extractCoordinate(String command, char axis) {
int axisIndex = [Link](axis);
if(axisIndex == -1) return [Link](axis);
int spaceIndex = [Link](' ', axisIndex);
if(spaceIndex == -1) spaceIndex = [Link]();
return [Link](axisIndex + 1, spaceIndex).toFloat();
}
};
6. Safety and Monitoring System
class SafetyMonitor {
private:
unsigned long lastSafetyCheck = 0;
const unsigned long SAFETY_INTERVAL = 1000; // 1 second
public:
void safetyCheck() {
if(millis() - lastSafetyCheck > SAFETY_INTERVAL) {
checkTemperature();
checkLimitSwitches();
checkPowerSupply();
lastSafetyCheck = millis();
}
}
void emergencyStop() {
// Stop all motors
digitalWrite(2, LOW);
digitalWrite(3, LOW);
// ... all motor pins
// Deactivate tool
analogWrite(TOOL_PWM, 0);
[Link](0);
// Set emergency state
[Link] = false;
}
private:
void checkTemperature() {
int tempReading = analogRead(TEMP_SENSOR);
float temperature = (tempReading * 5.0 / 1024.0) * 100;
if(temperature > 80.0) { // 80°C threshold
emergencyStop();
[Link]("EMERGENCY: Over temperature!");
}
}
void checkLimitSwitches() {
if(digitalRead(LIMIT_SWITCH_X) == LOW ||
digitalRead(LIMIT_SWITCH_Y) == LOW ||
digitalRead(LIMIT_SWITCH_Z) == LOW) {
emergencyStop();
[Link]("EMERGENCY: Limit switch triggered!");
}
}
void checkPowerSupply() {
// Monitor power supply voltage
int voltageReading = analogRead(A5);
float voltage = voltageReading * (5.0 / 1024.0) * 2; // Voltage divider
if(voltage < 10.0) { // Below 10V
emergencyStop();
[Link]("EMERGENCY: Low voltage!");
} } };
7. Main Program Setup
// Global objects
WeldingRobot welder;
CuttingRobot cutter;
GCodeInterpreter gcode;
SafetyMonitor safety;
void setup() {
[Link](9600);
// Initialize robot systems
[Link]();
[Link]("Robot Machining System Ready");
[Link]("Commands: WELD, CUT, GCODE, STOP");
}
void loop() {
[Link]();
if([Link]()) {
String command = [Link]('\n');
processCommand(command);
}}
void processCommand(String command) {
if([Link]("WELD")) {
// Example: "WELD STRAIGHT 100"
String params = [Link](5);
processWeldingCommand(params);
} else if([Link]("CUT")) {
// Example: "CUT SQUARE 50"
String params = [Link](4);
processCuttingCommand(params);
} else if([Link]("GCODE")) {
// Example: "GCODE G01 X100 Y50 F200"
String gcodeCommand = [Link](6);
[Link](gcodeCommand);
} else if([Link]("STOP")) {
[Link]();
}}
Ex8. Robot Programming and Simulation for Writing Practice
1. Core Writing Robot System Architecture
// Writing Robot for Practice - Arduino Code
#include <Stepper.h>
#include <Servo.h>
#include <EEPROM.h>
// Motor Configuration
#define STEPS_PER_REV 200
#define STEPS_PER_MM 20 // Steps per millimeter
// Stepper Motors for X-Y-Z axes
Stepper xAxis(STEPS_PER_REV, 2, 3, 4, 5);
Stepper yAxis(STEPS_PER_REV, 6, 7, 8, 9);
Stepper zAxis(STEPS_PER_REV, 10, 11, 12, 13);
// Pen Servo for up/down movement
Servo penServo;
const int PEN_SERVO_PIN = A0;
// Settings
const int PEN_UP_ANGLE = 60;
const int PEN_DOWN_ANGLE = 120;
const int WRITING_SPEED = 800;
const int MOVING_SPEED = 1200;
// Robot State
struct WritingState {
float x, y, z;
bool penDown;
float speed;
char currentChar;
};
WritingState robotState = {0, 0, 0, false, WRITING_SPEED, ' '};
2. Pen Control and Basic Movement
class PenController {
private:
bool isPenDown = false;
public:
void initialize() {
[Link](PEN_SERVO_PIN);
penUp();
}
void penDown() {
for(int angle = PEN_UP_ANGLE; angle <= PEN_DOWN_ANGLE; angle++) {
[Link](angle);
delay(15); }
isPenDown = true;
[Link] = true;
[Link]("Pen: DOWN");
}
void penUp() {
for(int angle = PEN_DOWN_ANGLE; angle >= PEN_UP_ANGLE; angle--) {
[Link](angle);
delay(15);
}
isPenDown = false;
[Link] = false;
[Link]("Pen: UP");
}
bool getPenState() {
return isPenDown;
} };
3. Coordinate Movement System
class MovementSystem {
private:
float maxX = 200; // mm
float maxY = 200; // mm
float maxZ = 50; // mm
public:
void setSpeed(float speed) {
[Link](speed);
[Link](speed);
[Link](speed);
[Link] = speed;
}
void moveTo(float targetX, float targetY, bool writeMode = false) {
// Constrain to limits
targetX = constrain(targetX, 0, maxX);
targetY = constrain(targetY, 0, maxY);
if(writeMode) {
setSpeed(WRITING_SPEED);
} else {
setSpeed(MOVING_SPEED);
}
// Calculate steps
long stepsX = (targetX - robotState.x) * STEPS_PER_MM;
long stepsY = (targetY - robotState.y) * STEPS_PER_MM;
// Execute movement
executeCoordinatedMove(stepsX, stepsY);
// Update position
robotState.x = targetX;
robotState.y = targetY;
}
void executeCoordinatedMove(long stepsX, long stepsY) {
long maxSteps = max(abs(stepsX), abs(stepsY));
for(long i = 0; i < maxSteps; i++) {
if(i < abs(stepsX)) {
if(stepsX > 0) [Link](1);
else [Link](-1);
}
if(i < abs(stepsY)) {
if(stepsY > 0) [Link](1);
else [Link](-1);
}
delayMicroseconds(1000000 / [Link]);
} }
void drawLine(float x1, float y1, float x2, float y2) {
moveTo(x1, y1, false);
penDown();
moveTo(x2, y2, true);
penUp();
} };
4. Character and Alphabet Writing System
class CharacterWriter {
private:
MovementSystem& mover;
PenController& pen;
public:
CharacterWriter(MovementSystem& m, PenController& p) : mover(m), pen(p) {}
void writeCharacter(char character, float startX, float startY, float size = 10.0) {
[Link] = character;
[Link]("Writing: ");
[Link](character);
switch(character) {
case 'A': drawA(startX, startY, size); break;
case 'B': drawB(startX, startY, size); break;
case 'C': drawC(startX, startY, size); break;
// Add more characters as needed
default: drawUnknown(startX, startY, size); break;
} }
void writeString(String text, float startX, float startY, float charSize = 10.0, float spacing =
3.0) {
float currentX = startX;
for(int i = 0; i < [Link](); i++) {
char c = [Link](i);
if(c == ' ') {
currentX += charSize * 0.7;
continue;
}
writeCharacter(c, currentX, startY, charSize);
currentX += charSize + spacing;
} }
private:
void drawA(float x, float y, float size) {
float h = size;
float w = size * 0.7;
[Link](x, y, x + w/2, y + h);
[Link](x + w/2, y + h, x + w, y);
[Link](x + w/4, y + h/2, x + 3*w/4, y + h/2);
}
void drawB(float x, float y, float size) {
float h = size;
float w = size * 0.6;
[Link](x, y, false);
[Link]();
[Link](x, y + h, true);
[Link](x + w, y + 3*h/4, true);
[Link](x, y + h/2, true);
[Link](x + w, y + h/4, true);
[Link](x, y, true);
[Link]();
}
void drawC(float x, float y, float size) {
float radius = size / 2;
drawArc(x + radius, y + radius, radius, PI/2, 3*PI/2, 16);
}
void drawUnknown(float x, float y, float size) {
// Draw question mark
drawCircle(x + size/2, y + size/4, size/4, 8);
[Link](x + size/2, y + size/2, x + size/2, y + size);
}
void drawCircle(float centerX, float centerY, float radius, int segments = 16) {
[Link](centerX + radius, centerY, false);
[Link]();
for(int i = 0; i <= segments; i++) {
float angle = 2 * PI * i / segments;
float x = centerX + radius * cos(angle);
float y = centerY + radius * sin(angle);
[Link](x, y, true);
}
[Link]();
}
void drawArc(float centerX, float centerY, float radius, float startAngle, float endAngle, int
segments) {
[Link](centerX + radius * cos(startAngle), centerY + radius * sin(startAngle),
false);
[Link]();
for(int i = 0; i <= segments; i++) {
float angle = startAngle + (endAngle - startAngle) * i / segments;
float x = centerX + radius * cos(angle);
float y = centerY + radius * sin(angle);
[Link](x, y, true);
}
[Link]();
}
};
5. Writing Practice Patterns
class WritingPractice {
private:
MovementSystem& mover;
PenController& pen;
CharacterWriter& writer;
public:
WritingPractice(MovementSystem& m, PenController& p, CharacterWriter& w)
: mover(m), pen(p), writer(w) {}
void linesPractice(float startX, float startY) {
[Link]("Starting lines practice");
// Horizontal lines
for(int i = 0; i < 5; i++) {
[Link](startX, startY + i*5, startX + 40, startY + i*5);
}
// Vertical lines
for(int i = 0; i < 5; i++) {
[Link](startX + 50 + i*5, startY, startX + 50 + i*5, startY + 20);
}
// Diagonal lines
for(int i = 0; i < 5; i++) {
[Link](startX + 80, startY + i*5, startX + 100, startY + (i+2)*5);
} }
void circlesPractice(float startX, float startY) {
[Link]("Starting circles practice");
for(int i = 1; i <= 5; i++) {
float radius = i * 3;
[Link](startX + radius * 2 * i, startY + 10, radius, 16);
} }
void alphabetPractice(float startX, float startY) {
[Link]("Starting alphabet practice");
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
float x = startX;
float y = startY;
for(int i = 0; i < [Link](); i++) {
if(i % 6 == 0 && i != 0) {
x = startX;
y += 15;
}
[Link](alphabet[i], x, y, 8);
x += 10;
} }
void wordsPractice(float startX, float startY) {
[Link]("Starting words practice");
String words[] = {"HELLO", "WORLD", "ROBOT", "WRITE", "LEARN"};
float y = startY;
for(int i = 0; i < 5; i++) {
[Link](words[i], startX, y, 8, 2);
y += 12;
} }
void signaturePractice(float startX, float startY) {
[Link]("Signature practice mode");
// Simulate a flowing signature motion
[Link](startX, startY, false);
[Link]();
// Signature-like curves
for(float t = 0; t <= 2*PI; t += 0.1) {
float x = startX + t * 8;
float y = startY + sin(t) * 4 + cos(2*t) * 2;
[Link](x, y, true);
}
[Link]();
} };
6. G-code Interpreter for Writing
class WritingGCode {
private:
MovementSystem& mover;
PenController& pen;
public:
WritingGCode(MovementSystem& m, PenController& p) : mover(m), pen(p) {}
void interpretGCode(String gcode) {
[Link]();
[Link]();
if([Link]("G00")) {
// Rapid move - pen up
[Link]();
rapidMove(gcode);
} else if([Link]("G01")) {
// Linear move - pen down
[Link]();
linearMove(gcode);
} else if([Link]("G04")) {
// Dwell/Pause
dwell(gcode);
} else if([Link]("M02")) {
// Program end
programEnd();
} else if([Link]("M03")) {
// Pen down
[Link]();
} else if([Link]("M05")) {
// Pen up
[Link]();
} }
private:
void rapidMove(String command) {
float x = extractCoordinate(command, 'X');
float y = extractCoordinate(command, 'Y');
[Link](x, y, false);
}
void linearMove(String command) {
float x = extractCoordinate(command, 'X');
float y = extractCoordinate(command, 'Y');
float f = extractCoordinate(command, 'F');
if(f > 0) [Link](f);
[Link](x, y, true);
}
void dwell(String command) {
float p = extractCoordinate(command, 'P');
delay(p);
}
void programEnd() {
[Link]();
[Link](0, 0, false);
[Link]("Program Complete");
}
float extractCoordinate(String command, char axis) {
int axisIndex = [Link](axis);
if(axisIndex == -1) return -1;
int spaceIndex = [Link](' ', axisIndex);
if(spaceIndex == -1) spaceIndex = [Link]();
return [Link](axisIndex + 1, spaceIndex).toFloat();
} };
7. Main Program with Interactive Menu
// Global objects
PenController pen;
MovementSystem mover;
CharacterWriter writer(mover, pen);
WritingPractice practice(mover, pen, writer);
WritingGCode gcodeInterpreter(mover, pen);
void setup() {
[Link](9600);
[Link]("=== Writing Robot System ===");
// Initialize systems
[Link]();
[Link](MOVING_SPEED);
// Home position
[Link](0, 0, false);
displayMenu();
}
void loop() {
if([Link]()) {
String command = [Link]('\n');
processCommand(command);
}
}
void displayMenu() {
[Link]("\n=== WRITING ROBOT MENU ===");
[Link]("1. Lines Practice");
[Link]("2. Circles Practice");
[Link]("3. Alphabet Practice");
[Link]("4. Words Practice");
[Link]("5. Signature Practice");
[Link]("6. Write Custom Text");
[Link]("7. G-code Mode");
[Link]("8. Home Position");
[Link]("9. Help");
[Link]("==========================");
}
void processCommand(String command) {
[Link]();
if(command == "1") {
[Link](10, 10);
} else if(command == "2") {
[Link](10, 10);
} else if(command == "3") {
[Link](5, 5);
} else if(command == "4") {
[Link](5, 5);
} else if(command == "5") {
[Link](10, 50);
} else if(command == "6") {
writeCustomText();
} else if(command == "7") {
gcodeMode();
} else if(command == "8") {
[Link](0, 0, false);
[Link]("Returned to Home");
} else if(command == "9") {
displayMenu();
} else if([Link]("G") || [Link]("M")) {
[Link](command);
} else {
[Link]("Unknown command. Type '9' for help.");
}
}
void writeCustomText() {
[Link]("Enter text to write:");
while(![Link]());
String text = [Link]('\n');
[Link]();
[Link]("Writing: ");
[Link](text);
[Link](text, 10, 50, 8, 2);
}
void gcodeMode() {
[Link]("G-code Mode Active. Enter commands:");
[Link]("G00 X# Y# - Rapid move");
[Link]("G01 X# Y# - Linear move");
[Link]("M03 - Pen down");
[Link]("M05 - Pen up");
[Link]("M02 - Program end");
while(true) {
if([Link]()) {
String command = [Link]('\n');
if(command == "exit") break;
[Link](command);
} }}
Ex. 9 Robot Programming and Simulation for Obstacle Avoiding Robot
#include <AFMotor.h>
#include <NewPing.h>
#include <Servo.h>
#define TRIG_PIN A1
#define ECHO_PIN A0
#define MAX_DISTANCE 200
#define MAX_SPEED 100 // sets speed of DC motors
#define MAX_SPEED_OFFSET 20
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);
AF_DCMotor motor1(1, MOTOR12_1KHZ);
AF_DCMotor motor2(2, MOTOR12_1KHZ);
AF_DCMotor motor3(3, MOTOR34_1KHZ);
AF_DCMotor motor4(4, MOTOR34_1KHZ);
Servo myservo;
boolean goesForward=false;
int distance = 100;
int speedSet = 0;
void setup() {
[Link](10);
[Link](115);
delay(2000);
distance = readPing();
delay(100);
distance = readPing();
delay(100);
distance = readPing();
delay(100);
distance = readPing();
delay(100);
}
void loop() {
int distanceR = 0;
int distanceL = 0;
delay(40);
if(distance<=20)
{
moveStop();
delay(100);
moveBackward();
delay(300);
moveStop();
delay(200);
distanceR = lookRight();
delay(200);
distanceL = lookLeft();
delay(200);
if(distanceR>=distanceL)
{
turnRight();
moveStop();
}else
{
turnLeft();
moveStop();
}
}else
{
moveForward();
}
distance = readPing();
}
int lookRight()
{
[Link](50);
delay(500);
int distance = readPing();
delay(100);
[Link](115);
return distance;
}
int lookLeft()
{
[Link](170);
delay(500);
int distance = readPing();
delay(100);
[Link](115);
return distance;
delay(100);
}
int readPing() {
delay(70);
int cm = sonar.ping_cm();
if(cm==0)
{ cm = 250;
} return cm; }
void moveStop() {
[Link](RELEASE);
[Link](RELEASE);
[Link](RELEASE);
[Link](RELEASE); }
void moveForward() {
if(!goesForward)
{
goesForward=true;
[Link](FORWARD);
[Link](FORWARD);
[Link](FORWARD);
[Link](FORWARD);
for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to
avoid loading down the batteries too quickly
{
[Link](speedSet);
[Link](speedSet);
[Link](speedSet);
[Link](speedSet);
delay(5);
} }}
void moveBackward() {
goesForward=false;
[Link](BACKWARD);
[Link](BACKWARD);
[Link](BACKWARD);
[Link](BACKWARD);
for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to
avoid loading down the batteries too quickly
{
[Link](speedSet);
[Link](speedSet);
[Link](speedSet);
[Link](speedSet);
delay(5);
}}
void turnRight() {
[Link](BACKWARD);
[Link](FORWARD);
[Link](FORWARD);
[Link](BACKWARD);
delay(500);
[Link](FORWARD);
[Link](FORWARD);
[Link](FORWARD);
[Link](FORWARD);
}
void turnLeft() {
[Link](FORWARD);
[Link](BACKWARD);
[Link](BACKWARD);
[Link](FORWARD);
delay(500);
[Link](FORWARD);
[Link](FORWARD);
[Link](FORWARD);
[Link](FORWARD);
}
Ex10. Robot Programming and Simulation for Line Following Robot
#include <AFMotor.h>
#define DEBUG_PRINT 0
#define LEFT_IR A3
#define RIGHT_IR A2
#define DETECT_LIMIT 300
#define FORWARD_SPEED 100
#define TURN_SHARP_SPEED 150
#define TURN_SLIGHT_SPEED 120
#define DELAY_AFTER_TURN 140
#define BEFORE_TURN_DELAY 10
AF_DCMotor motorL(1); // Uses PWM0B pin of Arduino Pin 5 for Enable
AF_DCMotor motorR(4); // Uses PWM0A pin of Arduino Pin 6 for Enable
int left_value;
int right_value;
char lastDirection = 'S';
void setup() {
#if DEBUG_PRINT
[Link](9600);
#endif
[Link](0);
[Link](RELEASE);
[Link](0);
[Link](RELEASE);
[Link](FORWARD);
[Link](FORWARD);
[Link](255);
[Link](255);
delay(40); // delay of 40 ms
}
void loop() {
left_value = analogRead(LEFT_IR);
right_value = analogRead(RIGHT_IR);
#if DEBUG_PRINT
[Link](left_value);
[Link](",");
[Link](right_value);
[Link](",");
[Link](lastDirection);
[Link](10);
#endif
if (right_value >= DETECT_LIMIT && !(left_value >= DETECT_LIMIT)) {
turnRight();
}
else if ((left_value >= DETECT_LIMIT) && !(right_value >= DETECT_LIMIT)) {
turnLeft();
}
else if (!(left_value >= DETECT_LIMIT) && !(right_value >= DETECT_LIMIT)) {
moveForward();
}
else if ((left_value >= DETECT_LIMIT) && (right_value >= DETECT_LIMIT)) {
moveBackward();
}
}
void moveForward() {
if (lastDirection != 'F') {
[Link](FORWARD);
[Link](FORWARD);
[Link](255);
[Link](255);
lastDirection = 'F';
delay(20);
} else {
[Link](FORWARD);
[Link](FORWARD);
[Link](FORWARD_SPEED);
[Link](FORWARD_SPEED);
}
}
void moveBackward() {
if (lastDirection != 'S') {
[Link](FORWARD);
[Link](FORWARD);
[Link](255);
[Link](255);
lastDirection = 'S';
delay(40);
} else {
[Link](0);
[Link](0);
[Link](RELEASE);
[Link](RELEASE);
lastDirection = 'S';
}
}
void turnRight(void) {
if (lastDirection != 'R') {
lastDirection = 'R';
[Link](0);
[Link](0);
delay(BEFORE_TURN_DELAY);
[Link](FORWARD);
[Link](BACKWARD);
[Link](TURN_SLIGHT_SPEED);
[Link](TURN_SLIGHT_SPEED);
} else {
// take sharp Right turn
[Link](FORWARD);
[Link](BACKWARD);
[Link](TURN_SHARP_SPEED);
[Link](TURN_SHARP_SPEED);
}
delay(DELAY_AFTER_TURN);
}
void turnLeft() {
// If first time Left Turn is taken
if (lastDirection != 'L') {
lastDirection = 'L';
// Stop the motor for some time
[Link](0);
[Link](0);
delay(BEFORE_TURN_DELAY);
// take slight Left turn
[Link](FORWARD);
[Link](BACKWARD);
[Link](TURN_SLIGHT_SPEED);
[Link](TURN_SLIGHT_SPEED);
} else {
// take sharp Left turn
[Link](FORWARD);
[Link](BACKWARD);
[Link](TURN_SHARP_SPEED);
[Link](TURN_SHARP_SPEED);
}
delay(DELAY_AFTER_TURN);
}