#include <Arduino.h>
#include <Servo.h>
#include "common.h"
#include "rate.h"
#define LEFT 0
#define MIDDLE 1
#define RIGHT 2
#define SPEED 3
#define RELAY_PIN 3
#define LEFT_BUTTON_PIN 4
#define MIDDLE_BUTTON_PIN 5
#define RIGHT_BUTTON_PIN 6
#define LEFT_SERVO_PIN 7
#define MIDDLE_SERVO_PIN 8
#define RIGHT_SERVO_PIN 9
#define SPEED_SERVO_PIN 10
#define OFF_TIMING 500
#define OPEN_ANGLE 100
#define RELAY_MIN_FLIP_TIME 1000
Servo servos[ 4 ] ;
#define leftServo ( servos[ LEFT ] )
#define middleServo ( servos[ MIDDLE ] )
#define rightServo ( servos[ RIGHT ] )
#define speedServo ( servos[ SPEED ] )
u8 wantedAngle[ 4 ] = { 0 } ;
u8 currentAngle[ 4 ] = { 0 } ;
u8 speedByPanels[ 4 ] = { 0, 35, 65, 100 } ;
union button {
u32 raw ;
u8 raw8[ 4 ] ;
struct {
u8 left ;
u8 middle ;
u8 right ;
u8 junk ;
};
};
union button buttonState, lastButtonState ;
u32 buttonDelay[ 3 ] = { 0 } ;
rate speed[ 4 ] ;
u32 tick ; // current tick
void setup() {
leftServo.attach( LEFT_SERVO_PIN );
middleServo.attach( MIDDLE_SERVO_PIN );
rightServo.attach( RIGHT_SERVO_PIN );
speedServo.attach( SPEED_SERVO_PIN );
pinMode( LEFT_BUTTON_PIN, INPUT_PULLUP );
pinMode( MIDDLE_BUTTON_PIN, INPUT_PULLUP );
pinMode( RIGHT_BUTTON_PIN, INPUT_PULLUP );
pinMode( RELAY_PIN, OUTPUT );
tick = millis() ;
rateStepBySecond( &speed[ LEFT ], 135 ) ; // 135° by second
rateStepBySecond( &speed[ MIDDLE ], 135 ) ;
rateStepBySecond( &speed[ RIGHT ], 135 ) ;
rateStepBySecond( &speed[ SPEED ], 135 ) ;
leftServo.write(0);
middleServo.write(0);
rightServo.write(0);
buttonState.raw = 0 ;
}
void readButtons( void ){
lastButtonState.raw = buttonState.raw ;
buttonState.left = digitalRead( LEFT_BUTTON_PIN ) ;
buttonState.middle = digitalRead( MIDDLE_BUTTON_PIN ) ;
buttonState.right = digitalRead( RIGHT_BUTTON_PIN ) ;
for( u8 n=LEFT; n<=RIGHT; n++ ){
if( buttonState.raw8[ n ] != lastButtonState.raw8[ n ] ){
if( !buttonState.raw8[ n ] ){ // just clicked
buttonDelay[ n ] = tick ;
} else { // just released
u32 d = tick - buttonDelay[ n ] ;
if( d < 30 ) break ;
if( d < OFF_TIMING ){
wantedAngle[ n ] = wantedAngle[ n ] ? 0 : OPEN_ANGLE ;
rateReset( &speed[ n ] ) ;
} else { // shutdown all
wantedAngle[ 0 ] = wantedAngle[ 1 ] = wantedAngle[ 2 ] = 0 ;
rateReset( &speed[ 0 ] ) ;
rateReset( &speed[ 1 ] ) ;
rateReset( &speed[ 2 ] ) ;
}
}
}
}
}
void loop() {
static u8 relayCurrentState = 0 ;
static u32 relayNextChange = tick ;
tick = millis() ;
readButtons();
u8 activePanels = 0 ;
// move servos to wanted angle
for( u8 n = LEFT; n <= SPEED; n++ ){
if( n != SPEED && wantedAngle[ n ] ) activePanels++ ;
int diff = wantedAngle[ n ] - currentAngle[ n ] ;
if( !diff ) continue ;
u32 p = rateUpdate( &speed[n] ) ;
if( diff < 0 ){
if( (int)p > -diff ) p = -diff ;
currentAngle[ n ] -= p ;
} else {
if( p > (u32)diff ) p = diff ;
currentAngle[ n ] += p ;
}
servos[ n ].write( currentAngle[ n ] ) ;
}
// automatic speed by number of open panels
u8 wantedSpeed = speedByPanels[ activePanels ] ;
if( wantedSpeed != wantedAngle[ SPEED ] ){
wantedAngle[ SPEED ] = wantedSpeed ;
rateReset( &speed[ SPEED ] ) ;
}
// relay state
u8 relayState = activePanels ? 1 : 0 ;
if( relayCurrentState != relayState && relayNextChange < tick ){
digitalWrite( RELAY_PIN, relayState ) ;
relayCurrentState = relayState ;
relayNextChange = tick + RELAY_MIN_FLIP_TIME ;
}
delay( 10 );
}
robinHood (./38886) :C'est une façon originale de faire un variateur électriquement isolé
— 🌞 Sol Brah 🌞 (@SolBrah) November 10, 2021
Zerosquare (./38892) :Pourquoi qu'on y a pas pensé avant ?— 🌞 Sol Brah 🌞 (@SolBrah) November 10, 2021