Dans le cadre de notre projet développement S2, nous devions concevoir un robot capable d’écrire des caractères avec un stylo, facile à utiliser et à moindre coût.
Nous avons pour cela décidé de construire un robot commandé par une application Android qui envoie par Bluetooth les caractères à écrire.
Notre robot est constitué d’un moteur et un train d’imprimante récupérés sur une vieille imprimante, 3 servomoteurs, une carte Arduino, une carte Ardumoto et des pièces pour relier le tout, imprimées à l’aide d’une imprimante 3D. Les pièces imprimées sont : les broches (qui constituent le bras du robot et qui servent à tenir le stylo) et la plate-forme pour relier le train d’imprimante et le bras. Le train d’imprimante va servir à translater le montage lorsqu’on a fini d’écrire un caractère. Deux des servomoteurs sont utilisés pour contrôler les broches qui tiennent le stylo et le troisième sert à soulever la plate-forme lorsque l’on veut déplacer le crayon sans écrire.
Le principe de notre robot consiste donc à envoyer des caractères en Bluetooth à partir de l’application et d’effectuer un traitement avec un code Arduino en fonction de la lettre reçue. À La réception d’un caractère, nous allons donc baisser le crayon, écrire le lettre reçue, lever le crayon et déplacer le dispositif avec le train d’imprimante pour écrire la prochaine lettre.
Cependant, les lettres écrites avec le robot sont très grandes car les servomoteurs ne sont pas assez précis donc on ne peut pas écrire des lettres de la taille de lettres manuscrites. Pour améliorer notre robot il faudrait donc utiliser des servomoteurs plus précis.
Code Arduino
#include <Servo.h>
#include <string.h>
Servo myservo1; //servo de gauche
Servo myservo2; //servo de droite
Servo myservo3; //servo qui soulève le crayon
#include <SoftwareSerial.h>
double pi = 3.141592654;
int bluetoothTx = 0; // on branche le TX du bluetooth à la broche 0 de l’arduino
int bluetoothRx = 1; // on branche le RX du bluetooth à la broche 1 de l’arduino
double distance = 9;
double angle_depart1 = 180;
double angle_depart2 = 90;
double l1 = 10;
double l2 = 12.5;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
#define CW 0
#define CCW 1
#define MOTOR_A 0
// constantes utilisées par Ardumoto : ne pas les changer!
const byte PWMA = 3; // la broche 3 est utilisée pour la puissance du moteur du train d’imprimante
const byte DIRA = 12; // la broche 12 est utilisée pour la direction
void setup() {
Serial.begin(9600); // Begin the serial monitor at 9600bps
//Setup bluetooth
delay(100); // Short delay, wait for the Mate to send back CMD
bluetooth.begin(9600); // Start bluetooth serial at 9600
//Setup servo
myservo1.attach(5); // attaches the servo on pin 9 to the servo object
myservo2.attach(9);
myservo3.attach(2);
Serial.println(« initialisation »);
myservo1.write(0);
myservo2.write(0);
myservo3.write(0);
//Setup Ardumoto
setupArdumoto();
stopArdumoto();
}
void loop()
{
if (bluetooth.available()) // A la réception d’un caractère
{
char text = (char)bluetooth.read();
Serial.print(« text = « );Serial.println(text);
bluetooth.print(text);
myservo3.write(20);
ecrire(text);
myservo3.write(20);
myservo1.write(0);
myservo2.write(0);
driveArdumoto(CCW, 150); // On translate le moteur
delay(100); // pendant 100 ms
stopArdumoto(); // et on le stoppe
}
}
void ecrire(char lettre)
{
if (lettre == ‘a’){
aller_en(-5.5,7);
myservo3.write(0);
aller_en(0,15.5);
aller_en(5.5,7);
aller_en(2.5,11.5);
aller_en(-2.5,11.5);
}
if (lettre == ‘b’){
aller_en(5,7);
myservo3.write(0);
aller_en(5,17);
aller_en(-5,17);
aller_en(-5,12);
aller_en(5,12);
aller_en(-5,12);
aller_en(-5,7);
}
if (lettre == ‘c’){
aller_en(-5,7);
myservo3.write(0);
aller_en(5,7);
aller_en(5,17);
aller_en(-5,17);
}
if (lettre == ‘d’){
aller_en(5,7);
myservo3.write(0);
aller_en(5,17);
aller_en(-5,17);
aller_en(-5,7);
}
if (lettre == ‘e’) {
aller_en(-5,7);
myservo3.write(0);
aller_en(5,7);
aller_en(5,17);
aller_en(-5,17);
myservo3.write(20);
aller_en(5,12);
myservo3.write(0);
aller_en(-5,12);
}
if (lettre == ‘f’) {
aller_en(5,7);
myservo3.write(0);
aller_en(5,17);
aller_en(-5,17);
myservo3.write(20);
aller_en(5,12);
myservo3.write(0);
aller_en(-5,12);
}
if (lettre == ‘g’) {
aller_en(-5,17);
myservo3.write(0);
aller_en(5,17);
aller_en(5,7);
aller_en(-5,7);
aller_en(-5,12);
aller_en(0,12);
}
if (lettre == ‘h’) {
aller_en(-5,7);
myservo3.write(0);
aller_en(-5,17);
myservo3.write(20);
aller_en(-5,12);
myservo3.write(0);
aller_en(5,12);
myservo3.write(20);
aller_en(5,7);
myservo3.write(0);
}
if (lettre == ‘i’) {
aller_en(0,7);
myservo3.write(0);
aller_en(0,17);
}
if (lettre == ‘j’) {
aller_en(-5,7);
myservo3.write(0);
aller_en(0,7);
aller_en(0,17);
}
if (lettre == ‘k’) {
aller_en(5,7);
myservo3.write(0);
aller_en(5,17);
myservo3.write(20);
aller_en(5,12);
myservo3.write(0);
aller_en(-5,17);
myservo3.write(20);
aller_en(5,12);
myservo3.write(0);
aller_en(-5,7);
}
if (lettre == ‘l’) {
aller_en(-5,7);
myservo3.write(0);
aller_en(5,7);
aller_en(5,17);
}
if (lettre == ‘m’) {
aller_en(-5,7);
myservo3.write(0);
aller_en(-5,17);
aller_en(0,12);
aller_en(5,17);
aller_en(5,7);
}
if (lettre == ‘n’) {
aller_en(5,7);
myservo3.write(0);
aller_en(5,17);
aller_en(-5,7);
aller_en(-5,17);
}
if (lettre == ‘o’) {
aller_en(5,7);
myservo3.write(0);
aller_en(5,17);
aller_en(-5,17);
aller_en(-5,7);
}
if (lettre == ‘p’) {
aller_en(5,7);
myservo3.write(0);
aller_en(5,17);
aller_en(-5,17);
aller_en(-5,12);
aller_en(5,12);
}
if (lettre == ‘q’) {
aller_en(5,7);
myservo3.write(0);
aller_en(5,17);
aller_en(-5,17);
aller_en(-5,7);
myservo3.write(20);
aller_en(0,12);
myservo3.write(0);
aller_en(-10,2);
}
if (lettre == ‘r’) {
aller_en(5,7);
myservo3.write(0);
aller_en(5,17);
aller_en(-5,17);
aller_en(-5,12);
aller_en(5,12);
aller_en(5,7);
}
if (lettre == ‘s’) {
aller_en(5,7);
myservo3.write(0);
aller_en(-5,7);
aller_en(-5,12);
aller_en(5,12);
aller_en(5,17);
aller_en(-5,17);
}
if (lettre == ‘t’) {
aller_en(0,7);
myservo3.write(0);
aller_en(0,17);
myservo3.write(20);
aller_en(5,17);
myservo3.write(0);
aller_en(-5,17);
}
if (lettre == ‘u’) {
aller_en(5,17);
myservo3.write(0);
aller_en(5,7);
aller_en(-5,7);
aller_en(-5,17);
}
if (lettre == ‘v’) {
aller_en(5,17);
myservo3.write(0);
aller_en(0,7);
aller_en(-5,17);
}
if (lettre == ‘w’) {
aller_en(5,17);
myservo3.write(0);
aller_en(2.5,7);
aller_en(0,12);
aller_en(-2.5,7);
aller_en(-5,17);
}
if (lettre == ‘x’) {
aller_en(-5,7);
myservo3.write(0);
aller_en(5,17);
myservo3.write(20);
aller_en(-5,17);
myservo3.write(0);
aller_en(5,7);
}
if (lettre == ‘y’) {
aller_en(0,7);
myservo3.write(0);
aller_en(0,12);
aller_en(-5,17);
myservo3.write(20);
aller_en(0,12);
myservo3.write(0);
aller_en(5,17);
}
if (lettre == ‘z’) {
aller_en(-5,7);
myservo3.write(0);
aller_en(5,7);
aller_en(-5,17);
aller_en(5,17);
}
if (lettre == ‘0’) {
aller_en(5,7);
myservo3.write(0);
aller_en(5,17);
aller_en(-5,17);
aller_en(-5,7);
}
if (lettre == ‘1’) {
aller_en(0,7);
myservo3.write(0);
aller_en(0,17);
aller_en(-5,12);
}
if (lettre == ‘2’) {
aller_en(-5,7);
myservo3.write(0);
aller_en(5,7);
aller_en(-5,12);
aller_en(-5,17);
aller_en(5,17);
aller_en(5,12);
}
if (lettre == ‘3’) {
aller_en(5,7);
myservo3.write(0);
aller_en(-5,7);
aller_en(-5,12);
aller_en(5,12);
myservo3.write(20);
aller_en(-5,12);
myservo3.write(0);
aller_en(-5,17);
aller_en(5,17);
}
if (lettre == ‘4’) {
aller_en(0,7);
myservo3.write(0);
aller_en(0,17);
aller_en(5,12);
aller_en(-5,12);
}
if (lettre == ‘5’) {
aller_en(5,12);
myservo3.write(0);
aller_en(5,7);
aller_en(-5,7);
aller_en(-5,12);
aller_en(5,17);
aller_en(-5,17);
}
if (lettre == ‘6’) {
aller_en(-5,17);
myservo3.write(0);
aller_en(5,17);
aller_en(5,7);
aller_en(-5,7);
aller_en(-5,12);
aller_en(5,12);
}
if (lettre == ‘7’) {
aller_en(5,7);
myservo3.write(0);
aller_en(-5,17);
aller_en(5,17);
}
if (lettre == ‘8’) {
aller_en(-5,7);
myservo3.write(0);
aller_en(5,7);
aller_en(5,12);
aller_en(-5,12);
aller_en(-5,17);
aller_en(5,17);
aller_en(5,12);
aller_en(-5,12);
aller_en(-5,7);
}
if (lettre == ‘9’) {
aller_en(5,7);
myservo3.write(0);
aller_en(-5,7);
aller_en(-5,17);
aller_en(5,17);
aller_en(5,12);
aller_en(-5,12);
}
else{
Serial.println(« mauvais caractère »);
bluetooth.print(« mauvais caractère »);
}
}
double angle1(double alpha){
double resultat = angle_depart1 – alpha;
return resultat;
}
double angle2(double alpha){
double resultat = angle_depart2 – alpha;
return resultat;
}
void aller_en(double x,double y){
double gamma1 = (atan2(y,x+distance/2))*(180/pi);
double c1 = sqrt(y*y + (x+distance/2)*(x+distance/2));
double truc = (l1*l1 + c1*c1 – l2*l2)/(2*l1*c1);
double beta1 = (180/pi)*acos(truc);
double alpha1 = beta1 + gamma1;
double gamma2 = (atan2(y,x-distance/2))*(180/pi);
double c2 = sqrt(y*y + (x-distance/2)*(x-distance/2));
double beta2 = (acos((l1*l1 + c2*c2 – l2*l2)/(2*l1*c2)))*(180/pi);
double alpha2 = gamma2 – beta2;
Serial.print(« le servo de gauche va a « );Serial.print(alpha1);Serial.println( » degrés »);
myservo1.write(angle1(alpha1));
Serial.print(« le servo de droite va a « );Serial.print(alpha2);Serial.println( » degrés »);
myservo2.write(angle2(alpha2));
delay(1000);
}
// driveArdumoto drives ‘motor’ in ‘dir’ direction at ‘spd’ speed
void driveArdumoto(byte dir, byte spd)
{
digitalWrite(DIRA, dir);
analogWrite(PWMA, spd);
}
// stopArdumoto makes a motor stop
void stopArdumoto()
{
driveArdumoto(0, 0);
}
// setupArdumoto initialize all pins
void setupArdumoto()
{
// All pins should be setup as outputs:
pinMode(PWMA, OUTPUT);
pinMode(DIRA, OUTPUT);
// Initialize all pins as low:
digitalWrite(PWMA, LOW);
digitalWrite(DIRA, LOW);
}
Hello,
Beau projet, ce serai encore mieux avec une vidéo de présentation du fonctionnement, pour le code c’est assez indigeste de le mettre sur une page comme ça, utilisez plutôt un site tel que github ou simplement un pastebin.
Comment transformez-vous la lettre « le caractère au sens informatique » en une forme physique : le tracé sur le papier ?