Bonjour,
je me présente en même temps que mon projet , Johann je suis mécanicien et touche à tout , j'ai fabriqué une imprimante type prusa i3 avec un plateau de 70cmX35cm en utilisant des vis mère donc grosse modif de code. Je m'amuse aussi avec solidworks et une cnc , enfin je suis un autodidacte et me défini comme assembleur.
je suis sur un projet de moniteur de température, avec affichage de l'heure de la date et des différentes températures relevées.
J'utilise une carte mega 2560 , une ramps 1.4 et un ecran 2004 avec lecteur sd et encoder rotatif.
Je suis donc dans une configuration sans entrés d'interruptions disponible car l'encodeur est relier aux pin 31 33 35 . J'ai écrit ,surtout modifié des codes et assemblés ceux ci , tout fonctionnait quand évidement j'ai voulu rajouter la ramps car le nombre de fils était source de faux contact.Donc les pin de mon encoder ont changés.
Y a t'il une solution simple sans changer complètement le code.
J'espère que mon poste respecte les règles c'est la première fois que je poste et je n'ai pas trouvé ou compris comment modifier la fonction attachinterrupt interne vers une autre fonction.
Merci pour votre aide
---------------------------------------------
`rotary_clock_quiet.ino
void setup() {
setup_lcd();
setup_rtc();
setup_encoder();
}
void loop( ) {
check_switch_condition();
long_push_timer();
release_timer();
event_dispatcher();
display_clock();
}
#define ON true
#define OFF false
---------------------------------------------
0_dispatcher.ino
// event dispatcher.
#define EVENT _00,_01,_02,_03,_04,_05,_06,_07,_08,_09,_10,_11
#define _BOOT 0 // _00() Initialize the adjustment mode
#define _IDLE 1 // _01() idling
#define _SELECT 2 // _02() select the commands
#define _DISPATCH 3 // _03() carry out the selected commands
#define _YEAR 4 // _04() adjust year
#define _MONTH 5 // _05() adjust month
#define _DATE 6 // _06() adjust date
#define _HOUR 7 // _07() adjust hour
#define _MINUTE 8 // _08() adjust minute
#define _SECOND 9 // _09() adjust second
#define _AMPMMT 10 // _10() change AM/PM MT mode
#define _DUMMY 11 // _11() prevent long press
static uint8_t EventID;
void ( *event[] )() = { EVENT };
void event_dispatcher( void ) { (*event[ EventID ])(); }
static uint8_t TemporaryEventID;
void event_switcher( uint8_t e ) {
TemporaryEventID = e;
EventID = _DUMMY;
}
---------------------------------------------
1_setup.ino
#include <Wire.h>
#include <LiquidCrystal.h>
const int rs = 16, en = 17, d4 = 23, d5 = 25, d6 = 27, d7 = 29;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup_lcd( void ){
lcd.begin(20, 4); }
// DS3231 Real Time Clock ( https://github.com/NorthernWidget/DS3231 )
#include <DS3231.h>
DS3231 clock; RTClib rtc;
void setup_rtc( void ) { Wire.begin(); set_dow(); }
// KY-040 Rotary Encoder
#define CLK 31 //2
#define DT 33 //3
#define SW 35 //A0
void setup_encoder( void ) {
pinMode( CLK, INPUT_PULLUP );
pinMode( DT, INPUT_PULLUP );
pinMode( SW, INPUT_PULLUP );
attachInterrupt( 0, isr_0, RISING );
attachInterrupt( 1, isr_1, RISING );
}
---------------------------------------------
2_encoder.ino
// rotary encoder
volatile uint8_t REGS1,REGS2;
volatile boolean CLK_PIN, DT_PIN;
volatile boolean Rotation = OFF;
volatile int16_t RotaryCounter;
volatile unsigned long ReleaseCounter;
void isr_0( void ) {
REGS1 = PIND & 0b00001100;
if ( ( REGS1 == 0b00001100 ) && CLK_PIN ) {
RotaryCounter--; ReleaseCounter = 0;
Rotation = ON; CLK_PIN = DT_PIN = LOW; sei();
} else if ( REGS1 == _BV(2) ) DT_PIN = HIGH;
}
void isr_1( void ) {
REGS2 = PIND & 0b00001100;
if ( ( REGS2 == 0b00001100 ) && DT_PIN ) {
RotaryCounter++; ReleaseCounter = 0;
Rotation = ON; CLK_PIN = DT_PIN = LOW; sei();
} else if ( REGS2 == _BV(3) ) CLK_PIN = HIGH;
}
#define RTMO 40 // Release time Maximum others.
#define RTMS 90 // Release time Maximum second.
static uint8_t ReleaseCounterMax = RTMO;
bool is_rotation( void ) {
bool r = Rotation;
if ( Rotation ) ReleaseCounter = ReleaseCounterMax;
Rotation = OFF;
return( r );
}
// builtin switch
static boolean DirectSwitch;
static boolean EdgeTriggerSwitch;
static boolean PreviousSwitch;
void check_switch_condition( void ) {
DirectSwitch = !digitalRead( SW ); // convert to positive logic
EdgeTriggerSwitch = DirectSwitch ^ PreviousSwitch & DirectSwitch; // rising
PreviousSwitch = DirectSwitch;
}
--------------------------------------------------------------------
3_release.ino
// rotary encoder switching mechanism.
#define INTERVAL_MILLIS 100
#define LONG_PUSH_COUNTER_MAX 8
static uint16_t LongPushCounter;
void long_push_timer ( void )
{
if ( !DirectSwitch ) { LongPushCounter = 0; return; }
static unsigned long pms, cms; cms = millis();
if ( cms - pms < INTERVAL_MILLIS ) return; else pms = cms;
if ( LongPushCounter == LONG_PUSH_COUNTER_MAX - 1 ) EventID = _AMPMMT;
if ( LongPushCounter < LONG_PUSH_COUNTER_MAX ) LongPushCounter++;
}
void release_timer ( void )
{
if ( DirectSwitch || Rotation ) { ReleaseCounter = ReleaseCounterMax; return; }
static unsigned long pms, cms; cms = millis();
if ( cms - pms < INTERVAL_MILLIS ) return; else pms = cms;
if ( ReleaseCounter > 0 ) ReleaseCounter--;
if ( ReleaseCounter == 1 ) {
EventID = _BOOT;
}
}
---------------------------------------------------------------------------
4_display.ino
// LCD display.
// several abbreviations.
#define months_of_the_year "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
#define days_of_the_week "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
// for the purpose of correction a leap year.
#define days_of_the_month 00, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 // ordinary year
// 00, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 // leap year
// days, weeks and months of the year
static const char *moy[] = { months_of_the_year };
static const char *dow[] = { days_of_the_week };
static const uint8_t dom[] = { days_of_the_month };
void display_clock ( void )
{
static unsigned long pms, cms; cms = millis();
if ( cms - pms < 50 ) return; else pms = cms;
static DateTime p;
static DateTime t;
t = rtc.now();
print_sec();
if ( t.minute() != p.minute() ) print_min();
if ( t.hour() != p.hour() ) { print_hour(); print_apm_str(); }
if ( t.day() != p.day() ) { print_date(); print_dow_str(); }
if ( t.month() != p.month() ) print_mon_str();
if ( t.year() != p.year() ) print_year();
print_temperature();
p = t;
}
bool Century = OFF;
bool h12;
bool PM;
void print_year( void ) {
lcd.setCursor( 0, 0 );
lcd.print( 2000 + clock.getYear(), DEC );
}
void print_mon_str( void ) {
lcd.setCursor( 5, 0 );
lcd.print( moy[clock.getMonth(Century) - 1 ] );
}
void print_date( void ) {
lcd.setCursor( 9, 0 );
add_zero( clock.getDate() );
}
void print_dow_str( void ) {
lcd.setCursor( 12, 0 );
set_dow();
lcd.print( dow[ clock.getDoW( ) - 1 ] );
}
static boolean Military = OFF;
void print_apm_str( void ) {
lcd.setCursor( 0, 1 );
if ( Military == OFF ) {
if ( clock.getHour(h12, PM) > 11 ) lcd.print( "PM ");
else lcd.print( "AM " );
} else lcd.print( "MT ");
}
void print_hour( void ) {
uint8_t val = clock.getHour(h12, PM);
if ( Military == OFF ) {
if ( clock.getHour(h12, PM) > 12 ) val -= 12;
if ( clock.getHour(h12, PM) == 0 ) val = 12;
}
lcd.setCursor( 3, 1 );
add_zero( val );
lcd.print( ":" );
}
void print_min( void ) {
lcd.setCursor( 6, 1 );
add_zero( clock.getMinute() );
lcd.print( ":" );
}
bool StopFlag;
void print_sec( void ) {
if ( StopFlag ) return;
lcd.setCursor( 9, 1 );
add_zero( clock.getSecond() );
}
static int8_t PrevTemp;
void print_temperature( void )
{
static int8_t currTemp;
currTemp = ( int8_t )clock.getTemperature();
if ( PrevTemp == currTemp ) return;
PrevTemp = currTemp;
lcd.setCursor( 11, 1 );
if ( currTemp < 0 ) lcd.print("-");
else lcd.print(" ");
add_zero( abs(currTemp) );
lcd.setCursor( 14, 1 );
lcd.print( char(223) );
lcd.print( "C" );
}
void clock_refresh( void )
{
PrevTemp = 100;
print_sec();
print_min();
print_hour();
print_apm_str();
print_dow_str();
print_date();
print_mon_str();
print_year();
print_temperature();
}
void set_dow( void )
{
int dow;
byte mArray[] = { 6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
DateTime t = rtc.now();
dow = ( t.year() % 100);
dow = dow * 1.25;
dow += t.day();
dow += mArray[ t.month() - 1];
if ((( t.year() % 4 ) == 0 ) && ( t.month() < 3 ) ) dow -= 1;
while (dow > 7) dow -= 7;
clock.setDoW( dow );
}
void add_zero( uint8_t val ) {
if ( val < 10 ) lcd.print( "0" );
lcd.print( val );
}
void select_active( void )
{
lcd.blink();
lcd.noCursor();
lcd.setCursor( 15, 0 );
lcd.print( "." );
}
void select_inactive( void )
{
lcd.noCursor();
lcd.noBlink();
lcd.setCursor( 15, 0 );
lcd.print( " " );
}
-------------------------------------------------
5_adjust.ino
// time settings.
/////////////////////////////////////////////////////////////////////////////////
// BOOT BOOT BOOT BOOT BOOT
/////////////////////////////////////////////////////////////////////////////////
void _00( void ) // _BOOT
{
StopFlag = OFF;
ReleaseCounterMax = RTMO;
LongPushCounter = 0;
ReleaseCounter = 0;
select_inactive();
clock_refresh();
EventID++;
}
/////////////////////////////////////////////////////////////////////////////////
// IDLE IDLE IDLE IDLE IDLE
/////////////////////////////////////////////////////////////////////////////////
void _01( void ) // _IDLE
{
if ( !EdgeTriggerSwitch ) return;
RotaryCounter = _YEAR;
select_active();
EventID++;
}
/////////////////////////////////////////////////////////////////////////////////
// SELECT SELECT SELECT SELECT SELECT
/////////////////////////////////////////////////////////////////////////////////
void _02( void ) // _SELECT
{
if ( is_rotation() ) return;
if ( RotaryCounter < _YEAR ) RotaryCounter = _SECOND;
if ( RotaryCounter > _SECOND ) RotaryCounter = _YEAR;
switch ( RotaryCounter ) {
case _YEAR : lcd.setCursor( 3, 0 ); break;
case _MONTH : lcd.setCursor( 7, 0 ); break;
case _DATE : lcd.setCursor( 10,0 ); break;
case _HOUR : lcd.setCursor( 4, 1 ); break;
case _MINUTE : lcd.setCursor( 7, 1 ); break;
case _SECOND : lcd.setCursor( 10,1 ); break;
}
if ( EdgeTriggerSwitch ) EventID++;
}
/////////////////////////////////////////////////////////////////////////////////
// DISPATCH DISPATCH DISPATCH DISPATCH
/////////////////////////////////////////////////////////////////////////////////
void _03( void ) // _DISPATCH
{
EventID = RotaryCounter;
switch ( EventID )
{
case _YEAR : RotaryCounter = clock.getYear() + 2000 ; break;
case _MONTH : RotaryCounter = clock.getMonth( Century ); break;
case _DATE : RotaryCounter = clock.getDate(); break;
case _HOUR : RotaryCounter = clock.getHour( h12, PM ); break;
case _MINUTE : RotaryCounter = clock.getMinute(); break;
case _SECOND : RotaryCounter = clock.getSecond(); break;
default : break;
}
lcd.cursor();
lcd.noBlink();
}
/////////////////////////////////////////////////////////////////////////////////
// YEAR YEAR YEAR YEAR YEAR YEAR
/////////////////////////////////////////////////////////////////////////////////
void _04( void ) // _YEAR
{
if ( RotaryCounter < 2000 ) RotaryCounter = 2099;
if ( RotaryCounter > 2099 ) RotaryCounter = 2000;
if ( is_rotation() ) {
clock.setYear( RotaryCounter - 2000 );
lcd.setCursor( 0, 0 );
lcd.print( RotaryCounter );
print_dow_str();
}
lcd.setCursor( 3, 0 );
if ( !EdgeTriggerSwitch ) return;
RotaryCounter = clock.getMonth( Century );
event_switcher( _MONTH );
}
/////////////////////////////////////////////////////////////////////////////////
// MONTH MONTH MONTH MONTH MONTH
/////////////////////////////////////////////////////////////////////////////////
void _05( void ) // _MONTH
{
if ( RotaryCounter > 12 ) RotaryCounter = 1;
if ( RotaryCounter < 1 ) RotaryCounter = 12;
if ( is_rotation() ) {
clock.setMonth( RotaryCounter );
print_mon_str();
print_dow_str();
}
lcd.setCursor( 7, 0 );
if ( !EdgeTriggerSwitch ) return;
RotaryCounter = clock.getDate();
event_switcher( _DATE );
}
/////////////////////////////////////////////////////////////////////////////////
// DATE DATE DATE DATE DATE DATE
/////////////////////////////////////////////////////////////////////////////////
void _06() // _DATE
{
static uint8_t dom[] = { 00, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if ( ( clock.getYear() % 4 ) == 0 ) dom[2] = 29; else dom[2] = 28;
if ( RotaryCounter > dom[ clock.getMonth(Century) ] ) RotaryCounter = 1;
if ( RotaryCounter < 1 ) RotaryCounter = dom[ clock.getMonth(Century) ];
if ( is_rotation() ) {
print_date();
clock.setDate( RotaryCounter );
print_dow_str();
}
lcd.setCursor( 10, 0 );
if ( !EdgeTriggerSwitch ) return;
RotaryCounter = clock.getHour( h12, PM );
event_switcher( _HOUR );
}
/////////////////////////////////////////////////////////////////////////////////
// HOUR HOUR HOUR HOUR HOUR HOUR
/////////////////////////////////////////////////////////////////////////////////
void _07( void ) // _HOUR
{
if ( RotaryCounter > 23 ) RotaryCounter = 0;
if ( RotaryCounter < 0 ) RotaryCounter = 23;
if ( is_rotation() ) {
print_hour();
clock.setHour( RotaryCounter );
print_apm_str();
}
lcd.setCursor( 4, 1 );
if ( !EdgeTriggerSwitch ) return;
RotaryCounter = clock.getMinute();
event_switcher( _MINUTE );
}
/////////////////////////////////////////////////////////////////////////////////
// MINUTE MINUTE MINUTE MINUTE MINUTE
/////////////////////////////////////////////////////////////////////////////////
void _08( void ) // _MINUTE
{
if ( RotaryCounter > 59 ) RotaryCounter = 0;
if ( RotaryCounter < 0 ) RotaryCounter = 59;
if ( is_rotation() ) {
clock.setMinute( RotaryCounter );
print_min();
}
lcd.setCursor( 7, 1 );
if ( !EdgeTriggerSwitch ) return;
RotaryCounter = clock.getSecond();
event_switcher( _SECOND );
}
/////////////////////////////////////////////////////////////////////////////////
// SECOND SECOND SECOND SECOND SECOND
/////////////////////////////////////////////////////////////////////////////////
void _09( void ) // _SECOND
{
if ( Rotation ) StopFlag = ON;
if ( RotaryCounter > 59 ) RotaryCounter = 0;
if ( RotaryCounter < 0 ) RotaryCounter = 59;
if ( is_rotation() ) {
lcd.setCursor( 9, 1 );
add_zero( RotaryCounter );
}
lcd.setCursor( 10, 1 );
ReleaseCounterMax = RTMS;
if ( !EdgeTriggerSwitch ) return;
clock.setSecond( RotaryCounter );
StopFlag = OFF;
event_switcher( _BOOT );
}
/////////////////////////////////////////////////////////////////////////////////
// AMPMMT AMPMMT AMPMMT AMPMMT AMPMMT
/////////////////////////////////////////////////////////////////////////////////
void _10( void ) // _AMPMMT
{
Military = !Military;
print_apm_str();
print_hour();
if ( EdgeTriggerSwitch ) return;
event_switcher( _BOOT );
}
/////////////////////////////////////////////////////////////////////////////////
// _DUMMY _DUMMY _DUMMY _DUMMY _DUMMY
/////////////////////////////////////////////////////////////////////////////////
void _11( void ) // _DUMMY
{
if ( DirectSwitch ) { lcd.noCursor(); lcd.noBlink(); return; }
EventID = TemporaryEventID;
lcd.cursor();
}