Souhaitez-vous participer à la création d'un jeu vidéo inspiré de Stardew Valley, ou le tester lorsque la version bêta sera disponible ? Remplissez notre sondage ou inscrivez-vous à notre lettre d'information (en bas de page)
1

arduino rotative welding table à vitesse constante

le 25-04-2015 à 15:13 #
Salut à tous,

ici un programme que j'ai écrit sur arduino UNO

14336 octets
cela donne de bons trucs pour utiliser un bouton encodeur mécanique un affichage rs232 LCD et le pilotage d'un moteur pas à pas avec acceleration

ci dessous versions avec les routines non utilisés et les traces de tests




Ici une version plus lisible


#include <rotary.h> //gestion du bouton encoder par interuption
#include <SoftwareSerial.h> // modification de softwareserial.ccp pcint2 mis en remarque
#include <AccelStepper.h> //gestion du moteur pas a pas

int Diameter = 150; //diametre de la pièce en mm variable
float ReductRatio = 22.5; //reduction mecanique totale
int NbOfStepPerRotSteper =1000; //reglage du controleur nb de step par tour
int WeldFwd =6; //soudage en avant
int WeldBwd = 3; //recouvrement WeldBwd
int Division =1; //nombre de divisions par tour
long int NbOfstepPerRot; //nombre de pas à effectuer pour que la table fasse 360 degres
float Perimeter=1.1;
float StepMmForDiam =1.1;
float NbOfStepInOneSec=1.1;
long int NbOfStepPerDiv;
int NbOfStepFwd;
int NbOfStepBwd;
long int SomeStepLeftToRun;
int MoveMenusw;


int sign = 1; // Holds -1, 1 or 0 to turn the motor on/off and control direction

byte PositionInScreen[8]={78,4,11,15,68,73,78,4};//field position of the screen
int x,xact=1;
byte IdxMenusw=4;

byte MultiplyBy10sw =1;//if pressed multiply by ten the value of rotary encoder

//0 free if used must be off for downloading
SoftwareSerial LCD(2,1); // RX, TX 2 is just for declaration
Rotary r = Rotary(2,3); //left pin to 2 middle pin to+5v right pin to 3
//4 free
//5 free
const byte ButtonCursblink = 6;//if pressed modify the value ob blinking pos
const byte ButtonMultiplyBy10 =7;//if pressed multiply by ten the value of rotary encoder
const byte ButtonCwCcw = 8;//if pressed change CW or CCW white
const byte ButtonMoveMenu = 9;// if pressed move in the menu and validate a parameter yellow
AccelStepper stepper1(1, 10, 11);
const byte ButtonOnOff = 12;//button on off feet of welder blue
// 13 used for enable

int WhichWay=1;
unsigned int MaxSpeed;

int WishedSpeedInMmMin = 100; //welding speed wished in mm per minute
byte DivisionLoop=0;//0 for looping division per 2 to 256
byte ExitFlag = 0; //flag for exiting a procedure
//byte StartMotor =0;//on off
String CwCcw ="L";//direction of rotation
String ToBePrinted= " ";//to update the field
int StepPerTurn= 1000; //number of steps per turn
int IncDec=1;// encoder increase or decrease
String Espace;// to clean the field
//-------------------------------------------------------------------------------------------
void setup()
{

LCD.begin(9600);// all SerLCDs come at 9600 Baud by default
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
pinMode(ButtonCursblink,INPUT_PULLUP);//if pressed modify the value ob blinking pos
pinMode(ButtonMultiplyBy10,INPUT_PULLUP);//if pressed multiply by ten the value of rotary encoder
pinMode(ButtonCwCcw,INPUT_PULLUP);//if pressed change CW or CCW
pinMode(ButtonMoveMenu,INPUT_PULLUP);// if pressed move in the menu and validate a parameter
pinMode(ButtonOnOff, INPUT_PULLUP);
stepper1.setCurrentPosition(0);
stepper1.moveTo(stepper1.currentPosition());
stepper1.setMaxSpeed(MaxSpeed);
stepper1.setAcceleration(1000);
stepper1.setEnablePin(13);

LCD.write(0xFE); //command flag
LCD.write(14); // 0x0E underlineCursorOn

basicValueForStepperMath ();
NbOfstepPerRot= NbOfStepPerRotSteper * ReductRatio; //final ratio of reduction to be modified in case of modif
diamSpeedCwCcw();
basicValueForStepperMath ();
NbOfstepPerRot= NbOfStepPerRotSteper * ReductRatio;

stepper1.setPinsInverted(false,false,true);

}
//-------------------------------------------------------------------------------------------
void loop()
{
if (!digitalRead( ButtonOnOff)) //if the pedal has not been pushed we look for some modification of parameters
{
stepper1.disableOutputs();

if (digitalRead(ButtonCwCcw))//do we have rotation inversed the value of step should be multipli by sign
{
ExitFlag = false; // no screen update
sign*= -1;//
if (sign==1) CwCcw = "R"; else CwCcw = "L";
ToBePrinted = CwCcw;
MoveMenusw=15;
updateScreen();
basicValueForStepperMath ();
stepper1.setCurrentPosition(0);
stepper1.moveTo(stepper1.currentPosition());
stepper1.moveTo(abs(NbOfStepPerDiv)*sign);

delay(1000);
}

if (digitalRead(ButtonMultiplyBy10))// the button X 10 pressed ?
{
ExitFlag=false; //no screen update
if (MultiplyBy10sw==10) MultiplyBy10sw=1; else MultiplyBy10sw=10;

delay(350);
}

encodRotary();
}
else
{

stepper1.enableOutputs();
if (Division<2)
stepper1.run();

else
{
stepper1.setMaxSpeed(6000);
stepper1.run();
}

encodRotary();
}

if (stepper1.distanceToGo() == 0)
{
switch (Division)
{

case 0:

modeBackAndForth();
break;

case 1:
{
delay(2500);
turnDisplayOff();
delay(500);
turnDisplayOn();
basicValueForStepperMath ();
stepper1.setCurrentPosition(0);
stepper1.moveTo(stepper1.currentPosition());
stepper1.moveTo(abs(NbOfStepPerDiv)*sign);
stepper1.setSpeed(NbOfStepInOneSec);
}
break;

default:
{
if(DivisionLoop-->0)
{
stepper1.setMaxSpeed(6000);
stepper1.moveTo(abs(NbOfStepPerDiv)*sign);
delay(2500);

}
else
{
DivisionLoop= Division;
stepper1.setCurrentPosition(0);
stepper1.moveTo(stepper1.currentPosition());
stepper1.moveTo(abs(NbOfStepPerDiv)*sign);
delay(1500);
turnDisplayOff();
delay(1500);
turnDisplayOn();
}
}
}
}
}

void encodRotary()
{
if(x!=xact) //rotary encoder has moved
{
if (x>xact)
IncDec=1; //value to add
else
IncDec=-1;
xact=x;
ExitFlag=true;

if (digitalRead(ButtonMoveMenu))
{
ExitFlag=false;
if (IncDec<0)
IdxMenusw++;
else
IdxMenusw--;
moveCursor();
}

if (digitalRead(ButtonCursblink))
{ ExitFlag=false;
switch (IdxMenusw)
{
case 0:

IdxMenusw=6;

break;

case 1:

Diameter+=(MultiplyBy10sw*IncDec);
Espace =" ";
ToBePrinted = String(Diameter);
updateScreen();
basicValueForStepperMath ();
break;

case 4:

Division+=IncDec;
Espace =" ";
ToBePrinted = String(Division);
updateScreen();
basicValueForStepperMath ();
if (Division==0) modeBackAndForth();
break;

case 5:

WeldFwd+=IncDec;
Espace =" ";
ToBePrinted = String(WeldFwd);
updateScreen();
basicValueForStepperMath ();
break;

case 6:

WeldBwd+=IncDec;
Espace =" ";
ToBePrinted = String(WeldBwd);
updateScreen();
basicValueForStepperMath ();
break;

case 7:

IdxMenusw=1;

break;
}

}
if (ExitFlag) // if rotary move and no button increment/decrement speed
{

int SaveIdxMenusw = IdxMenusw; //save current state
int SaveMoveMenusw=MoveMenusw;
String SaveEspace =Espace;
IdxMenusw=2;//position the value on Mm /minute
moveCursor();
Espace=" ";
stepper1.run();
ToBePrinted = String(WishedSpeedInMmMin+=(MultiplyBy10sw*IncDec));// to call a function that update calculation
speedinStepSec(); // call a function that update calculation

stepper1.setSpeed(NbOfStepInOneSec);
updateScreen();
// LCD.print(String(sign*NbOfStepInOneSec));

IdxMenusw=SaveIdxMenusw; //restore previous state
MoveMenusw=SaveMoveMenusw;
Espace=SaveEspace;
// digitalWrite(LedX10, LOW); pour debug only
moveCursor();
}
}
}


//-------------------------------------------------------------------------------------------
void modeBackAndForth()
{
if (SomeStepLeftToRun>0) //here determine how to deal with cwccw
{ stepper1.setCurrentPosition(0);
stepper1.moveTo(stepper1.currentPosition());
if (WhichWay==1)
{
//stepper1.moveTo((NbOfStepFwd+NbOfStepBwd)*sign);//it wil go CW or CCW depend of sign
stepper1.moveTo(NbOfStepFwd*sign);//it wil go CW or CCW depend of sign
WhichWay =-1;//next time I will go reverse
SomeStepLeftToRun-=NbOfStepFwd;//nb of step forward will be taking off from the total

}
else
{

stepper1.moveTo((-NbOfStepBwd)*sign);
WhichWay =1;
SomeStepLeftToRun+=NbOfStepBwd;
}
stepper1.setSpeed(NbOfStepInOneSec);
}
else
//make some fun with the screen to indicate Job done
{
delay(200);
turnDisplayOff();
delay(1000);
turnDisplayOn();
//Serial.println(stepper1.distanceToGo());
stepper1.setCurrentPosition(0);
stepper1.moveTo(stepper1.currentPosition());
SomeStepLeftToRun=NbOfStepPerDiv;
}
}
//-------------------------------------------------------------------------------------------
void moveCursor()
{
//byte PositionInScreen[8]=(78,4,11,16,68,72,78,4)
//moves the cursor left one space
MoveMenusw=PositionInScreen[IdxMenusw];
LCD.write(0xFE); //command flag
LCD.write(128+MoveMenusw); // 0x10
LCD.write(0xFE); //command flag
LCD.write(0x0D); // 0x10

}
//-------------------------------------------------------------------------------------------
void updateScreen()
{
LCD.write(0xFE); //command flag
LCD.write(128+MoveMenusw); //
LCD.print(Espace);
stepper1.run();
LCD.write(0xFE); //command flag
LCD.write(128+MoveMenusw); //
LCD.print(ToBePrinted);
LCD.write(0xFE); //command flag
LCD.write(128+MoveMenusw); // 0x10
moveCursor();

}
//-------------------------------------------------------------------------------------------

void turnDisplayOff()
{
//this tunrs the display off, but leaves the backlight on.
LCD.write(0xFE); //command flag
LCD.write(8); // 0x08
}
//-------------------------------------------------------------------------------------------
void turnDisplayOn()
{
//this turns the dispaly back ON
LCD.write(0xFE); //command flag
LCD.write(12); // 0x0C
}
//-------------------------------------------------------------------------------------------
void diamSpeedCwCcw()
{
// LCD.write(0xFE);// clearScreen1();
LCD.write(0xFE); //command flag
LCD.write(128); //position selectLineOne();
LCD.print("Dia=");
LCD.print(Diameter,DEC);
LCD.print(" ");
LCD.print("Mm=");
LCD.print(WishedSpeedInMmMin,DEC);
LCD.print(" ");
LCD.print(CwCcw);
LCD.write(0x01);//clearScreen2();
LCD.write(0xFE); //command flag
LCD.write(192); //position selectLineTwo();
LCD.print("Div=");
LCD.print(Division,DEC);
LCD.print(" ");
LCD.print("F=");
LCD.print(WeldFwd,DEC);
LCD.print(" ");
LCD.print("B= ");
LCD.print(WeldBwd,DEC);
}
//-------------------------------------------------------------------------------------------

ISR(PCINT2_vect) {//interuption for mechanical rotary encoder
//ISR(PCINT4_vect)
unsigned char result = r.process();
if (result) {
if (result == DIR_CW )
{ x++; } else { x--; }
}
}

void basicValueForStepperMath ()
{
diamSpeedCwCcw();
Perimeter = Diameter* PI;
StepMmForDiam = Perimeter/ NbOfstepPerRot; // float value of length for one step at the perimeter could be 0.055850536
speedinStepSec();
if (Division>0) numberOfStepPerSector();
else
{
Division=1;//to avoid division per zero
numberOfStepPerSector();
NbOfStepFwd =WeldFwd/StepMmForDiam; //how far to weld forward and backward this number will be take off from the nmber to run
NbOfStepBwd = WeldBwd/StepMmForDiam; // create mask and field for input of value weld forward and backward when field division is > 1
Division=0;
}

}

void speedinStepSec()
{
NbOfStepInOneSec = (WishedSpeedInMmMin / StepMmForDiam)/60 ; //usefull
stepper1.setMaxSpeed(NbOfStepInOneSec);//this speed is not valid for mode pointing
}

void numberOfStepPerSector()
{
NbOfStepPerDiv = NbOfstepPerRot / Division; //how many step to weld a point
stepper1.moveTo(abs(NbOfStepPerDiv)*sign);//warning here for test it must be set depending the mode
stepper1.setSpeed(NbOfStepInOneSec);
}






(Modifié par rokag3 le 25-04-2015 à 15:37)

Ajout du 25-04-2015 à 16:39:




Ma version finale vas piloter 4 moteurs pas à pas
un moteur pour la rotation de la table 0 à 360 degrés
un moteur d'inclinaison de la table de 45 à 225 degrés (peut être de façon dynamique )
un moteur pas à pas pour l'alimentation du fil de soudure pour TIG ou MIG
un moteur pour l'oscillation de la torche 180 degrés (dynamique) piloté à partir de la position 90degré exemple 45 100 signifie 45 degrés en amont et 10 degrés en aval avec vitesse d'oscillation variable.

un système de démarrage sur présence d'arc
un système d'ajustage des différentes valeurs d'accélérations
peut être un module de lecture des paramètres de Fronius magicwave (si je parviens à obtenir les infos electriques et logiciels)
encore peut être une programmation en Gcode
Re: arduino rotative welding table à vitesse constante
le 25-04-2015 à 20:17 #
Hello,

merci pour le partage !!!
Ca servira sans doute ! (en tout cas, moi, ça va me servir )

@++
toy
Re: arduino rotative welding table à vitesse constante
le 26-04-2015 à 13:35 #
J'apprécie Toy,

Si tu as des questions n'hésite pas, l'affichage se fait avec un lcd pilote par une rs232, c'est plus cher mais cela consomme moins de temps machine et moins d'IO

la routine de pilotage de l'encodeur bouton rotatif est une petite merveille, les encodeurs mécaniques vus au scope sont de sinistres mer.e mais cette routine transforme ces signaux bouillie de chat en quelque chose de parfaitement utilisable.
Re: arduino rotative welding table à vitesse constante
le 27-04-2015 à 08:23 #
Hello Rokag,

nous allons en priorité nous équiper de packs complets pour mon asso de ce type -> http://www.adafruit.com/products/68
Nous nous équiperons sans doute de TFTs pour aller avec -> http://www.adafruit.com/products/1651

Ensuite...et bien nous allons bosser sur plusieurs produits Nous avons déjà monté un Raspberry dans une vieille console Nintendo64 pour en faire un émulateur multi-plateformes, et ça fonctionne pas trop mal, on a eu un problème avec le refroidisseur qui faisait planter le Raspberry -_-

Mais avec les données que tu as postées, on va avancer plus vite sur des projets, j'en suis sûr :)
Re-merci !

@+
toy
Re: arduino rotative welding table à vitesse constante
le 27-04-2015 à 14:15 #
Sincèrement je pense que c'est cher
http://www.banggood.com/Arduino-UNO-R3-Advanced-Module-Kit-Electronic-Learning-For-Arduino-p-965085.html

je suis passé par eux et rien à dire c'est parfait


Ajout du 27-04-2015 à 14:52:

Je pense qu'un écran TFT qui ne coute que 11$ http://www.banggood.com/UNO-R3-ATmega328P-Board-2_4-Inch-TFT-LCD-Screen-Module-For-Arduino-p-945755.htmln'est pas adapté à Arduino UNO manque de vitesse et de memoire, le domaine d'Arduino c'est le petit automatisme, si l'on veut faire dans le plus sophistiqué il faut passer par l'Arduino due
http://www.banggood.com/Arduino-Compatible-DUE-R3-32-Bit-ARM-With-USB-Cable-p-906466.html

Je te conseille de n'acheter qu'un carte arduino UNO d'origine et une carte Due d'origine pour deux raisons.
1 donner du fric à Arduino qui en a besoin
2 disposer d'une référence de test
bien que les clowns ne posent en général pas de problèmes il est parfois psychologiquement important de disposer de certitudes

Ajout du 27-04-2015 à 15:16:

ce programme fonctionne avec la UNO il y a un problème avec la MEGA l'interruption pour l'encodeur rotatif de la librairie rotary.h
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
correspond au 328 je vais donc changer la librairie pour utiliser quadrature.h dans la mesure ou le seul changement de l'interruption ne règle pas tous les problèmes, mais la librairie rotary.h est la plus légère .
Re: arduino rotative welding table à vitesse constante
le 29-04-2015 à 19:14 #
Site de vente plus intéressant ! Merci bien :)
Re: arduino rotative welding table à vitesse constante
le 18-09-2017 à 02:25 #
Cool j'avais perdu l'explication du conflit et je vais recompiler avec une nouvele version de librairie accestepper je vais devoir (peut être) bidouiller les interruptions

Moralité on ne documente jamais suffisamment ses programmes, quand on écrit les remarques on trouve qu'on se prend pour un débile et quand on relis 2 ans plus tard on trouve que l'on aurais pu être un peu plus bavard

La morale de cette morale, c'est que nous sommes beaucoup plus débile crétin que nous le supposons

(Modifié par rokag3 le 18-09-2017 à 02:26)




Ces discussions pourraient vous intéresser également:


arduino ampli op et potentiomètre digital
programmation carte arduino et relier au détecteur
Arduino redondance securité naissance d'un projet
pied à coulisse électronique affichage déporté DRO arduino
Aide pour démarrer avec arduino pour des enfants