Bonsoir TheFloys
J'ai un peu fouillé dans mes programmes et retrouvé et réadapté le programme de gestion des "règles chinoises"
Je te mets le code
// Digital Linear Scale DLS
#include <TimerOne.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20, 4); // 0x27 = adresse sur bus i2C, peut être 0x3f
#define dlsSsyPin 4 // Pin d'horloge en direction du DLS
#define dlsDataPin 5 // Pin des données recues du DLS
#define dlsOffsetResetPin 7 // Pour mettre l'offset à 0
boolean dlsTimeToRead = false; // Si c'est le moment de lire la DLS
long dlsPositionMM100;
float dlsPositionMM;
long dlsOffset;
void setup()
{
Serial.begin(115200);
pinMode(dlsSsyPin, OUTPUT);
digitalWrite(dlsSsyPin, LOW);
pinMode(dlsDataPin, INPUT_PULLUP);
pinMode(dlsOffsetResetPin, INPUT_PULLUP);
lcd.begin();
lcd.noBacklight();
delay(500);
lcd.backlight();
Timer1.initialize(250000); // Timer toutes les quarts de sconde
Timer1.attachInterrupt(timer1deadline); // attach the service routine here
dlsPositionMM100 = 0;
dlsOffset = dlsGetPosition(0, dlsSsyPin, dlsDataPin); // On prend la position de la règle comme 0 mm.
Serial.println("Regle Shahe (DLS)");
lcdPrint("Regle Shahe (DLS)", 0, 0);
}
void loop()
{
if (dlsTimeToRead) // Temps de lire le ou les PAC de type DLS
{
dlsPositionMM100 = dlsGetPosition(dlsOffset, dlsSsyPin, dlsDataPin);
dlsPositionMM = (float)dlsPositionMM100/100;
Serial.println("1/100mm\t" + String(dlsPositionMM100));
Serial.println("mm\t" + String(dlsPositionMM));
lcdPrint("mm", 0, 1);
lcdPrintLength(String(dlsPositionMM), 6, 1, 7);
lcdPrint("100mm", 0, 2);
lcdPrintLength(String(dlsPositionMM100), 6, 2, 7);
dlsTimeToRead = false;
}
if (digitalRead(dlsOffsetResetPin)== 0) // Si bouton offset reset pressé donc 0 ou LOW
{
delay(100);
dlsOffset = dlsGetPosition(0, dlsSsyPin, dlsDataPin);
}
}
//-------------------------------- Timer1
void timer1deadline()
{
dlsTimeToRead = true;
}
long dlsGetPosition(long offsetDls, int pinSsy, int pinData)
{
int dlcBitOffset;
long dlsMeasureValue = 0;
for(dlcBitOffset = 0; dlcBitOffset<20; dlcBitOffset++) // Lecture des 20 premiers bits
{
digitalWrite(pinSsy, HIGH);
delayMicroseconds(10); // Impulsion d'horloge vers dls
digitalWrite(pinSsy, LOW);
dlsMeasureValue |= (!digitalRead(pinData)<<dlcBitOffset); // Inverser le bit parceque à travers un transistor
}
//------------------------------------------- lecture du dernier bit (21)
digitalWrite(pinSsy, HIGH);
delayMicroseconds(10);
digitalWrite(pinSsy, LOW);
if(digitalRead(pinData) != HIGH) // Inverser le bit parceque à travers un transistor
{
dlsMeasureValue |= (0x7ff << 21);
}
return dlsMeasureValue - offsetDls;
}
//---------------------------------------------------------------------------------------
// Diverses routines pour faciliter l'usage de l'affichage LCD
//---------------------------------------------------------------------------------------
String lcdEmptyLine = " ";
//---------------------- Effacement écran
void lcdCls()
{
lcd.clear();
}
//---------------------- Effacement de la ligne rowNum
void lcdClsRow(int rowNum)
{
lcdPrint(lcdEmptyLine, 0, rowNum);
}
//---------------------- Afficher texte Colonne Ligne
void lcdPrint(String lcdText, int lcdCol,int lcdRow)
{
lcd.setCursor(lcdCol,lcdRow);
lcd.print(lcdText);
}
//---------------------- Afficher texte de longueure déterminée
void lcdPrintLength(String lcdText, int lcdCol,int lcdRow, int textLength)
{
String textToLength = lcdText + lcdEmptyLine;
textToLength = textToLength.substring(0,textLength);
lcdPrint(textToLength, lcdCol, lcdRow);
}
Adaptes les paramètres de l'affichage LCD i2C.
et le schéma
pour finir,
une petite vidéo.
Il est bien claire, ce n'est pas la seule solution pour faire ton capteur d'échelle, il y a les codeur rotatifs à incréments, les règles magnétiques qui sont aussi traitées comme des codeurs rotatifs, mais c'est, je pense, le moins chère et le plus facile à mettre en oeuvre.
A ta disposition pour de plus amples renseignements.
Cordialement
jpbbricole