NOTE
: Alain A. m'a gentiment proposé sa version du source, même
code mais commentaires plus détaillés en Français:
C'est téléchargeable ICI
Et voici le source :
/* CP0097 Rotating
Plate Control Copyright Cyrob 2019 Arduino pro Micro
Description
Control a Stepper
motor in two modes: - SpeedMode : The
speed varie with the knob position from -max to max with a midle zero
position
Led is switched off if the motor is stopped
Led is green if it moves
Led is red is the maximum speed is reached
- TrackMode : The
position of the motor follows the knob one
The increment of the position change with the speed of the knob to
allow precision
Led is blue
Pushing the knob at
any time stops the motor ans toggle mode.
The motor windings
are desactivated when motor is Off
===================================================================================== ==========================
OPEN SOURCE LICENCE
================================== =====================================================================================
Copyright 2019
Philippe Demerliac Cyrob.org
Permission is hereby
granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright
notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT.
IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
................................................................................................................ Release history ................................................................................................................ Version
Date
Author Comment 1.0d1
02/02/19 Phildem First blood 1.0
06/02/19 Phildem Version OK 1.1
06/02/19 Phildem Version OK, relative
speed improvement 1.2
07/02/19 Phildem Version OK, Code
refactoring and presentation */
//IO Abstraction
............................................................................................... #define
kOutCpuLed 13 // Active High #define
kOutRLed 12
// Active Low #define
kOutGLed 11
// Active Low #define
kOutBLed 10
// Active Low
#define
kOutDir
8 #define
kOutStep
9 // Step on Low to High
transition #define
kOutEnable 5 //
Active Low
// Settings
.................................................................................................... #define
kMicroIdle
20
// Micro Ticker step duration in µs #define
kStepPulseWidth_us
4
// Step pulse width in µS #define
kMotorWakeUp_ms
10
// Delay in ms to let motor wake up when Enable set to low
#define
kMinSpeedDelay_uT
10000 //
Slower speed in delay between Step pulse in Micro idle steps #define
kMaxSpeedDelay_uT
100
// Higher speed in delay between Step pulse in Micro idle steps #define
kMaxSpeed
100
// Max Value of gSpeed #define
kSpeedInc
5
// Knob increment for Speed #define
kPosInc
2
// Knob pos Increment in TrackMode
// Global
..................................................................................................... static unsigned
long
gLastMicro
=0; //
Micro Ticker last Time ref static unsigned
long
gLastMilli
=0; //
Milli Ticker last Time ref
static
long
gSpeed
=0; // 0
Off else -kMaxSpeed to +kMaxSpeed Sign is dir static unsigned
long
gPulseDelay
=0; //
Delay counter in Micro Ticker between pulse static
bool
gMotEnable
= false; // True if motor enable
static
bool
gLastKnobCk;
// Last knob Ck Input static unsigned
long
gLastKnobMilli
=0; // Last
milli of knob action
static
bool
gModeTrack
= false; // True if mode Track static unsigned
long
gTargetPos
=0; //
Track mode Target pos static unsigned
long
gActualPos
=0; //
Track mode Actual pos
// Test
Led Sequence
digitalWrite(kOutCpuLed, HIGH);
SetLedRed();
delay(500);
SetLedGreen();
delay(500);
SetLedBlue();
delay(500);
for (int
i=0;i<5;i++){
SetLedRed();
delay(20);
SetLedOff();
delay(150); }
digitalWrite(kOutCpuLed, LOW);
SetModeSpeed(); }
//============================================================================================================ // UI Led Control //____________________________________________________________________________________________________________
//------------------------------------------------------------------------------------------------------------ // Switch State Led
to Red //------------------------------------------------------------------------------------------------------------ void SetLedRed(){
digitalWrite(kOutRLed, LOW);
digitalWrite(kOutGLed, HIGH);
digitalWrite(kOutBLed, HIGH); }
//------------------------------------------------------------------------------------------------------------ // Switch State Led
to Green //------------------------------------------------------------------------------------------------------------ void SetLedGreen(){
digitalWrite(kOutRLed, HIGH);
digitalWrite(kOutGLed, LOW);
digitalWrite(kOutBLed, HIGH); }
//------------------------------------------------------------------------------------------------------------ // Switch State Led
to Blue //------------------------------------------------------------------------------------------------------------ void SetLedBlue(){
digitalWrite(kOutRLed, HIGH);
digitalWrite(kOutGLed, HIGH);
digitalWrite(kOutBLed, LOW); }
//------------------------------------------------------------------------------------------------------------ // Switch State Led
to Off //------------------------------------------------------------------------------------------------------------ void SetLedOff(){
digitalWrite(kOutRLed, HIGH);
digitalWrite(kOutGLed, HIGH);
digitalWrite(kOutBLed, HIGH); }
//------------------------------------------------------------------------------------------------------------ // Handle
Led display must be call every ms //------------------------------------------------------------------------------------------------------------ void LedIdle() { if
(gModeTrack)
SetLedBlue(); else if
(gSpeed==0)
SetLedOff(); else if
(abs(gSpeed)>=kMaxSpeed)
SetLedRed(); else
SetLedGreen(); }
//------------------------------------------------------------------------------------------------------------ // Look if knob
moved, return 0 if not, else -Step or +Step vs direction //------------------------------------------------------------------------------------------------------------ long ReadKnob() {
bool Ck=digitalRead(kInKnobCk);
if
(Ck==gLastKnobCk)
return 0;
delayMicroseconds(400);
gLastKnobCk=Ck;
if
(Ck==LOW)
return 0;
unsigned
long Step; unsigned
long Now=millis(); if
(gModeTrack){
// Non linear in Track mode
gLastKnobMilli=Now-gLastKnobMilli;
Step=kPosInc;
if
(gLastKnobMilli<350)
Step*=8;
else if (gLastKnobMilli<500)
Step*=4;
else if (gLastKnobMilli<600)
Step*=2; } else
Step=kSpeedInc;
gLastKnobMilli=Now; if
(digitalRead(kInKnobDir)==LOW) // Set Sign vs
direction
return -Step; return
Step; }
//------------------------------------------------------------------------------------------------------------ // Handle
Knob rotation, must be call every Micro Ticker //------------------------------------------------------------------------------------------------------------ void KnobRotIdle() {
long
k=ReadKnob();
if (k==0)
return;
if
(gModeTrack) {
SetRelativeTrackPosition(k); } else
SetSpeed(gSpeed+k); }
//------------------------------------------------------------------------------------------------------------ // Handle
Knob Push must be call every ms //------------------------------------------------------------------------------------------------------------ void KnobPushIdle(){
if
(digitalRead(kInKnobPush)==HIGH)
return; // Wait
for button released while
(digitalRead(kInKnobPush)==LOW)
delay(1);
// Toggle
mode if
(gModeTrack){ //
Return to speed mode
SetModeSpeed(); } else
{
// Return to Track mode
SetModeTrack(); } }
//============================================================================================================ // Motor Control //____________________________________________________________________________________________________________
//------------------------------------------------------------------------------------------------------------ // Increment motor
of one step //------------------------------------------------------------------------------------------------------------ void StepOne() {
digitalWrite(kOutStep, HIGH);
delayMicroseconds(kStepPulseWidth_us);
digitalWrite(kOutStep, LOW); }
//------------------------------------------------------------------------------------------------------------ // Enable motor power //------------------------------------------------------------------------------------------------------------ void EnableMotor(){
digitalWrite(kOutCpuLed, HIGH);
digitalWrite(kOutEnable, LOW); if
(!gMotEnable) // To let driver wake up
delay(kMotorWakeUp_ms);
gMotEnable=true; }
//------------------------------------------------------------------------------------------------------------ // Disable motor
power //------------------------------------------------------------------------------------------------------------ void DisableMotor(){
digitalWrite(kOutCpuLed, LOW);
digitalWrite(kOutEnable, HIGH);
gMotEnable=false; }
//------------------------------------------------------------------------------------------------------------ // Set Global Speed,
sign is direction, Speed will be clamp to max //------------------------------------------------------------------------------------------------------------ void SetSpeed(long
Speed) {
//------------------------------------------------------------------------------------------------------------ // Handle Motor,
make it turn vs gSpeed. Must be called every Micro Ticker //------------------------------------------------------------------------------------------------------------ void MotorIdle() { if
(gSpeed==0){
DisableMotor();
return; }
//============================================================================================================ // Mode Control //____________________________________________________________________________________________________________
//------------------------------------------------------------------------------------------------------------ //
Indicate to switch to mode Speed //------------------------------------------------------------------------------------------------------------ void SetModeSpeed(){
gModeTrack=false;
SetSpeed(0); }
//------------------------------------------------------------------------------------------------------------ //
Indicate to switch to mode Track //------------------------------------------------------------------------------------------------------------ void SetModeTrack(){
gModeTrack=true;
gActualPos=0;
gTargetPos=0;
SetSpeed(0); }
//------------------------------------------------------------------------------------------------------------ // Set the
target position in Track Mode (Pos or neg vs Dir) //------------------------------------------------------------------------------------------------------------ void
SetRelativeTrackPosition(long Move){
gTargetPos+=Move; }
//------------------------------------------------------------------------------------------------------------ // Handle
Mode must be call every ms //------------------------------------------------------------------------------------------------------------ void ModeIdle(){ if
(!gModeTrack)
return;
if
(gActualPos==gTargetPos){
gActualPos=0;
gTargetPos=0;
SetSpeed(0); } else
SetSpeed(gTargetPos-gActualPos); }
//============================================================================================================ //
Cooperativ multi task supervisor //____________________________________________________________________________________________________________
//------------------------------------------------------------------------------------------------------------ // Main
Loop //------------------------------------------------------------------------------------------------------------ void loop(void) { // µs
Ticker ................................... unsigned
long CurMicro=micros(); if
(CurMicro<gLastMicro){
// Handle µ Rollover
gLastMicro=CurMicro; }
if
((CurMicro-gLastMicro)>kMicroIdle){
gLastMicro=CurMicro;
// Fast Engine -------------
MotorIdle();
// Fast UI UI -------------
KnobRotIdle(); } // ms
Ticker ................................ unsigned
long CurMilli=millis(); if
(CurMilli !=gLastMilli){
gLastMilli=CurMilli;
Les pistes en lignes facilitent les liaisons sur ce genre de montages
Les junpers pemettent de choisir la résolution, j'ai finalement opté
pour du 1/4 de pas.
J'ai découpé le bouton dans une chute de plastique avec une scie cloche
sans centre.
Puis fait une fixation d'axe en soudant un raccord 'Mecano" sur une
plaque de cuivre.
Le tout est monté sur un suppor pour rendre le bouton afleurant.
Toutes ces tôles de recup diverses me servent toujours....
Le plateau, je vais le couvrir d'un tapis 'Gomme' une foit terminé.
J'ai usiné le support qui va bien dans une chute d'alu
Ce
site utilise des frames. Si vous ne voyez pas
les menus à gauche, cliquez
Ici