J'arrive au bout de mon proto, du moins côté "hard".
Reste maintenant à développer des programmes complets.
Edit 20.1.12 : Attention, correction ! Prévoyez dès maintenant un déplacement du fil (jaune ici) opto pin D2 vers A2 !! (analogique 2)
Ceci pour libérer les pins D2 et D3, utilisées par les interruptions programmables (capt. de fin de course / stop d'urgence).
A corriger aussi dans le code ci-dessous !
J'ai réalisé un petit programme test (très simple), il peut déjà servir en l'état pour faire du stacking semi assisté !
On choisi la distance des pas (foulée) puis on avance chaque foulée en appuyant sur un bouton. On shoot avec un autre.
(noter aussi en début de code l’assignation de toutes les E/S (pin) utilisées pour ce proto)
Nb: Ce montage est configuré pour l'instant en pas entier.
Comparé au mode 1/16ème de pas (microsteping) il y a aussi beaucoup plus de vibrations entre les pas.
Le code :
/!\ Voir correction à faire (Pin Opto) en tête de message /!\
et remplacer
const int PinShoot = 2; // Pin optocoupleur shoot
par
const int PinShoot = 16; // Pin optocoupleur shoot (Pin A2 en digital = 16 !)
Edit du 13.02.12 : Modif programme test, ne relâche plus le moteur entre les pas + ajout compteur et divers.
(Faire un Reset pour libérer le moteur et remettre le compteur à zéro. Pensez aussi à régler la fréquence moteur si vous avez des problèmes de précision !)
- Code: Tout sélectionner
/*******************************************************
* Stepduino proto
* Ch.Aubert, Janv. 2012
*
********************************************************/
/************* Librairie(s) à inclure ****************/
#include <LiquidCrystal.h>
/**************** Définir des caractères spéciaux LCD (8 caractères max) ********************/
// Flèche haut
byte Char_UP[8] = {
B00000, B00000, B00100, B01110, B11111, B00000, B00000, B00000};
// Flèche bas
byte Char_DOWN[8] = {
B00000, B00000, B11111, B01110, B00100, B00000, B00000, B00000};
// Flèche droite
byte Char_RIGHT[8] = {
B00000, B00000, B10000, B11000, B11100, B11000, B10000, B00000};
// Flèche gauche
byte Char_LEFT[8] = {
B00000, B00000, B00001, B00011, B00111, B00011, B00001, B00000};
// Select
byte Char_SELECT[8] = {
B00000, B00000, B01110, B01110, B01110, B01110, B00000, B00000};
// Car.vide (pour avoir un index zéro dans mes tableaux)
byte Char_NONE[8] = {
B00000, B00000, B00000, B00000, B00000, B00000, B00000, B00000};
/**************** Fin caractères spéciaux LCD ********************/
/************* Définition des broches (pins) du LCD 5 boutons DFRobot ****************/
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
const int PinLCDBacklight = 10; // broche LCD Backlight
const int PinBouton = A0; // broche analogique (A0) utisé pour les 5 boutons
/************* Définition des autres E/S ****************/
const int PinDir = 11; // DIR
const int PinStep = 12; // STEP
const int PinEnable = 13; // ENABLE (est partagé avec le Led 13 de l'Arduino !)
const int PinBuzzer = 17; // Pin analogique 3 = 17 !!
const int PinShoot = 2; // Pin optocoupleur shoot
//const int PinShoot = 16; // A2 Pin optocoupleur shoot : Pin analogique 2 en digital = 16 !
// A4 et A5 à réserver si LCD I2C (2 broches) est employé !
// D2 et D3 à réserver pour les IRQ (int. programmables, bouton stop et détect. fin de course. Modif à faire pour l'opto en D2!)
/************* Constantes programme ****************/
//Moteur PAP
const int Const_DefautPas = 10; // Foulée par défaut (nb. de pas à la fois, ou distance pas)
const int Const_TempFoulee = 300; // Temporisation entre les foulées de pas
const int Const_tempo_bouton = 200; // Temporisation appui bouton
// APN
const int Const_ShootPressDelay = 100; // Délais "bouton" Shoot
const int Const_InterPictureDelay = 500; // Délais entre PDV
// Définition et numérotation des boutons
const int btnRIGHT = 1;
const int btnUP = 2;
const int btnDOWN = 3;
const int btnLEFT = 4;
const int btnSELECT = 5;
const int btnNONE = 6;
/************* Variables ****************/
byte lcd_key = 0;
int adc_key_in = 0;
unsigned int dPas = Const_DefautPas;
int compteur = 0;
/************* Setup ****************/
void setup()
{
// Moteur PAP
pinMode(PinEnable, OUTPUT); // broche Enable en sortie
digitalWrite(PinEnable, HIGH); // On met un niveau haut sur Enable pour relacher le moteur !!
pinMode(PinStep, OUTPUT); // Dir et Step en sortie
pinMode(PinDir, OUTPUT);
digitalWrite(PinStep, HIGH);
digitalWrite(PinDir, HIGH);
// initialiser la LCD library, 16 caractères, 2 lignes
lcd.begin(16, 2);
// Création des caractères (symboles) LCD personnalisés. à placer après "LCD.begin" (ou .init) sinon ça bug !!
lcd.createChar(1, Char_RIGHT); // Flèche droite
lcd.createChar(2, Char_LEFT); // Flèche gauche
lcd.createChar(3, Char_UP); // Flèche haut
lcd.createChar(4, Char_DOWN); // Flèche bas
lcd.createChar(5, Char_SELECT); // Carré select
pinMode(PinLCDBacklight, OUTPUT); // Broche LCD backlight en sortie
digitalWrite(PinLCDBacklight, HIGH); // Retro-éclairage actif (par défaut il est déjà mais je le justifie ici)
// APN (opto)
pinMode(PinShoot, OUTPUT); // Pin Optocoupleur en sortie
//pinMode(PinFocus, OUTPUT); // Pin opto en sortie (si focus installé)
//pinMode(PinLedArduino, OUTPUT); // Déjà utilisé par PinEnable !
// Buzzer
pinMode(PinBuzzer, OUTPUT);
//tone(PinBuzzer, 2500, 25); // Bip
// LCD Accueil
lcd.setCursor(0,0); // placer le curseur à la première ligne, première position
lcd.print("Stepduino proto "); // texte d'accueil
lcd.setCursor(0,1); // placer le curseur au début de la seconde ligne
lcd.print("Le Naturaliste");
delay(1500);
lcd.clear();
} // end setup
/************* Boucle principale ****************/
void loop()
{
lcd_key = read_LCD_buttons(); // lire la valeur du bouton (->fonction)
switch (lcd_key) // selon le bouton appuyé ...
{
case btnRIGHT: // tourner à DROITE (en fonction des branchements de votre moteur !)
// paramètre fonction Go_PAP : Sens de rotation (0 ou 1), distance pas (foulée), temporisation moteur
//(règle la fréquence : Plus on augmente la temp. plus on diminue la fréq. !)
// Sens de rotation : 0 = LOW, 1=HIGH
// Attention, chez moi en pas entier et au_dessous d'une temporisation moteur de 1000 us
//le moteur n'arrive plus à faire de grandes foulée (>10) !!
Go_PAP(1, dPas, 3000);
compteur++;
LCD_ligne_1();
delay(Const_TempFoulee);
//digitalWrite(PinEnable, HIGH); // On relache le moteur (on peut le tourner à la main)
break;
case btnLEFT: // tourner à GAUCHE (en fonction des branchements de votre moteur !)
Go_PAP(0, dPas, 3000);
compteur--;
LCD_ligne_1();
delay(Const_TempFoulee);
//digitalWrite(PinEnable, HIGH); // On relache le moteur (on peut le tourner à la main)
break;
case btnUP:
LCD_ligne_1();
dPas ++; // augmenter foulée de pas
if (dPas <= 1) dPas = 1;
delay(Const_tempo_bouton); // tempo bouton
break;
case btnDOWN:
LCD_ligne_1();
dPas --; // diminuer foulée de pas
if (dPas <= 1) dPas = 1;
delay(Const_tempo_bouton); // tempo bouton
break;
case btnSELECT:
takePicture(); // SHOOT !!
delay(Const_InterPictureDelay); // Délais entre PDV
break;
case btnNONE:
LCD_ligne_1();
lcd.setCursor(0,1); // placer le curseur au début de la seconde ligne
lcd.print("Re");
lcd.write(2); // fl.gauche
lcd.print(" Av");
lcd.write(1); // fl.droite
lcd.print(" Shoot");
lcd.write(5); // select
break;
}
} // end loop
/************* Sous programmes ****************/
///// Tourner PAP ////////
void Go_PAP(boolean dir_pap, int dist_Pas, int freq_mot) {
digitalWrite(PinEnable, LOW); // active le moteur (il ne sera plus possible de le tourner à la main et l'ampérage sera à son MAX !!
digitalWrite(PinDir, dir_pap); // Tourne à gauche ou à droite
for(int j = 1; j <= dist_Pas; j++) { // foulée de pas
digitalWrite(PinStep, LOW);
delayMicroseconds(10); // à ajuster selon moteur, on peut essayer de diminuer à 2 us
digitalWrite(PinStep, HIGH);
delayMicroseconds(freq_mot); // temporisation à ajuster selon moteur (contrôle la fréquence, la vitesse et le couple)
}
} // end func
// Shoot Reflex
void takePicture() {
//digitalWrite(PinFocus, HIGH); // (si focus installé)
//delay(FocusPressDelay); // (si focus installé)
tone(PinBuzzer, 2500, 25); // Bip
digitalWrite(PinShoot, HIGH);
delay(Const_ShootPressDelay);
digitalWrite(PinShoot, LOW);
//digitalWrite(PinFocus, LOW); // (si focus installé)
}
// Affichage LCD ligne 1
void LCD_ligne_1 () {
lcd.setCursor(0,0); // placer le curseur à la première ligne, première position
lcd.write(3); // fl.haut
lcd.write(4); // fl.bas
lcd.print(" dPas=");
lcd.print(dPas);
lcd.print(" #");
lcd.print(compteur);
lcd.print(" ");
}
/************* Fonctions ****************/
// Lire la valeur A/D retournée selon le bouton choisi
int read_LCD_buttons()
{
adc_key_in = analogRead(PinBouton);
if (adc_key_in > 1000) return btnNONE; // On commence par la valeur la plus probable : Aucun appui sur bouton !
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
return btnNONE; // si aucun appui sur bouton, on retoune la constante btnNONE ...
} // end func.
Réf :
Carte de puissance moteur : viewtopic.php?f=282&t=10443#p52627
Ecran LCD 5 boutons : viewtopic.php?f=283&t=10242
Carte proto + optocoupleur : viewtopic.php?f=285&t=10421
Code plus abouti (pour LCD DFRobot) : Voir viewtopic.php?f=284&t=11092