Probleme avec affichage LCD2004_IC2

Salut a tous
J'ai prix une programmation de sur Github pour un controlleur de hauteur de torch plasma.
L'écran LCD spécifier je ne les pas,
Jai cahnger les deux line et inclus la bibliotéque de la nouvelle LCD.
Le probleme et que je les deja fait sur un autre logiciel et sa la fonctionne de remplacer les deux ligne comme ci :
//#include <LiquidCrystal.h> // Enlever Louis

#include <LiquidCrystal_I2C.h> //LG

// RS, RW (optional, faster in general), E, D4-7

LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display //LG

//LiquidCrystal lcd(1, 2, 3, 4, 5, 6, 7); //EN LG

Mais le probleme et que suite a ceci le build fonctionne mais le LCD ne affiche rien ?

Aussi j'essaie de remplacer le bouton par un encoder KY-040.

PS Je suis débrouillard mais débutant:(
Aussi ceci et travaillé sur VScode
Voici le code que je essaie de modifier:
Texte préformaté

#ifndef TORCHHEIGHTCONTROL_H_
#define TORCHHEIGHTCONTROL_H_



/*
 *  Main libraries
 */
// already contains all necessary AVR's and C standard library functions
#include <Arduino.h>

/*
 *  User libraries
 */
// We use custom ADC library instead of Arduino's analogRead()
// because second takes some unwanted for us periphery (timer)
// and it is actually quite simple to write your own lightweight version
// of analogRead() so why not?
#include <ADC.h>
// Abstraction layer for the way we rule the motor. There can be a driver
// for a stepper motor plus set of switches, a stepper motor with
// "intelligent" step-direction driver, simply DC motor or whatever you wants to.
#include <MotorDriver.h>


/*
 *  Control signals definitions (all of them are inputs)
 *  Free (unused) pins:
 *    - PB5 (can be used as a test LED)
 *    - PD0
 *    - PD1
 */
#define SIGNALS_DDR DDRB
#define SIGNALS_PIN PINB
#define UP_SIGNAL_PIN PB2 // PIN 10
#define UP_SIGNAL_INT PCINT2
#define DOWN_SIGNAL_PIN PB3 //PIN 11
#define DOWN_SIGNAL_INT PCINT3
#define PLASM_SIGNAL_PIN PB4 //PIN 12
#define PLASM_SIGNAL_INT PCINT4
#define TOUCH_SIGNAL_PIN PB1 //PIN 9
#define TOUCH_SIGNAL_INT PCINT1
#define SETTINGS_BUTTON_PIN PB0 //PIN 8
#define SETTINGS_BUTTON_INT PCINT0
// initial state: all signals are pulled up to Vcc
uint8_t signals_port_history = 0xFF;


/*
 *  Menu definitions
 */
enum Menu {
    WORK_MENU,
    IDLE_MENU,
    cutting_height_MENU,
    SETPOINT_OFFSET_MENU,
    PIERCE_TIME_MENU,

    NUM_OF_MENUS
};
uint8_t menu = IDLE_MENU;  // initial state


/*
 *  LCD definitions. We use Arduino's standard library LiquidCrystal for this
 *  because of its robustness and widespread
 */
//#include <LiquidCrystal.h> // Enlever Louis
#include <LiquidCrystal_I2C.h> //LG
// RS, RW (optional, faster in general), E, D4-7
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display //LG
//LiquidCrystal lcd(1, 2, 3, 4, 5, 6, 7); //EN LG 
// we need slightly more than the length of a string (16 in our case)
// due to the inner structure of the sprintf(). Otherwise, displayed
// values can be corrupted
#define BUFFER_SIZE 25
char bufferA[BUFFER_SIZE];  // 1st raw of LCD
char bufferB[BUFFER_SIZE];  // 2nd raw of LCD


/*
 *  LED for testing purposes. PB5 is built-in on UNO and NANO
 */
// #define TEST_LED
#ifdef TEST_LED
    #define TEST_LED_DDR DDRB
    #define TEST_LED_PORT PORTB
    #define TEST_LED_PIN PB5
#endif



#endif /* TORCHHEIGHTCONTROL_H_ */

Ensuite il y as ceci qui rentre dans la configuration:

#include <TorchHeightControl.h>



/*
 *  Other settings
 */
// Lift before cut is measured in steps of stepper motor (0-1023).
// EEMEM is the default value at the flash time. Actually, not so important
// because we always can change it at runtime
uint16_t cutting_height;  // cutting_height
uint16_t EEMEM cutting_height_EEPROM = 150;
// Pierce time is measured in ELEMENTARY_DELAYs which in turn is measured in ms
uint8_t pierce_time;
#define PIERCE_TIME_ELEMENTARY_DELAY 100  // 100 ms
#define PIERCE_TIME_MAX_TIME 50  // 50*ELEMENTARY_DELAY = 5s max
uint8_t EEMEM pierce_time_EEPROM = 20;  // 20*ELEMENTARY_DELAY = 2000ms
// Flag of the "bypass mode" without regulation. We explicitly use uint8_t type
// (instead of bool) because AVR's EEPROM driver has function for that
uint8_t EEMEM bypass_ON_flag_EEPROM = 0;


/*
 *  Setpoint settings
 */
uint16_t setpoint = 0;
// setpoint will be automatically defined at regulation start
#define NUM_OF_VALUES_FOR_SETPOINT_DEFINITION 200
bool setpoint_defined = false;
// hysteresis for control algorithm (setpoint ± setpoint_offset)
uint16_t setpoint_offset;
uint16_t EEMEM setpoint_offset_EEPROM = 20;  // 97mV
// interval of voltages for specifing setpoint offset in settings menus, Volts
#define SETPOINT_OFFSET_MIN_SET_VOLTAGE 0.010
#define SETPOINT_OFFSET_MAX_SET_VOLTAGE 0.200


/*
 *  Signal from arc and control algorithm definitions. Note that we use shared
 *  feedback variables first for setpoint defining and then for main regulation
 *  algorithm itself
 */
uint16_t feedback = 0;  // 10-bit ADC value
uint16_t feedback_prev = 0;  // previous ADC value
uint32_t feedback_accum = 0;  // accumulator for averaging
uint16_t feedback_accum_cnt = 0;  // counter of num of values for averaging
uint16_t feedback_avrg = 0;
// counter for manual dividing frequency of algo' timer in its ISR
uint8_t prescaler_cnt = 0;
#define PRESCALER_MAIN_ALGO 50
// hysteresis for averaging only close results of ADC measurements
#define OFFSET_FOR_AVRG 10  // ±48mV



int main(void) {

    // disable all interrupts while setup
    cli();

    /*
     *  Debug LED
     */
    #ifdef TEST_LED
        TEST_LED_DDR |= (1<<TEST_LED_PIN);
        TEST_LED_PORT &= ~(1<<TEST_LED_PIN);
    #endif

    /*
     * LCD startup
     */
    lcd.init(); //AJ LG
    lcd.backlight(); // AJ LG
    lcd.begin(16, 2);
    lcd.clear();
    lcd.setCursor(0,0); //AJ LG
    lcd.print("loading...");
    delay(2000); //100 //AJ LG
    lcd.clear(); // AG LG
    /*
     *  Retrieve values from EEPROM
     */
    setpoint_offset = eeprom_read_word(&setpoint_offset_EEPROM);
    cutting_height = eeprom_read_word(&cutting_height_EEPROM);
    pierce_time = eeprom_read_byte(&pierce_time_EEPROM);

    /*
     *  Set directions of IOs
     */
    // outputs:
    // MOTOR_DDR |= (1<<MOTOR_PHASE_A)|(1<<MOTOR_PHASE_B)|(1<<MOTOR_PHASE_C)|(1<<MOTOR_PHASE_D);
    // inputs:
    SIGNALS_DDR &= ~( (1<<SETTINGS_BUTTON_PIN) | (1<<UP_SIGNAL_PIN) | (1<<DOWN_SIGNAL_PIN) |
                      (1<<PLASM_SIGNAL_PIN) | (1<<TOUCH_SIGNAL_PIN) );

    /*
     *  Interrupts setup (so far only for up, down and settings button pins)
     */
    PCICR |= (1<<PCIE0);
    PCMSK0 |= (1<<SETTINGS_BUTTON_INT) | (1<<UP_SIGNAL_INT) | (1<<DOWN_SIGNAL_INT);

    /*
     *  Timer0 for the torch height control algorithm
     */
    // CTC mode
    TCCR0A |= (1<<WGM01);
    // 1000 Hz frequency (formula from datasheet) (CONFIRMED). For getting actual frequency
    // of controlling divide this frequency on PRESCALER_MAIN_ALGO
    OCR0A = 124;
    // Set prescaler to 64 and start the timer
    TCCR0B |= (1<<CS01)|(1<<CS00);
    // We don't have dedicated controlling procedure as we use interrupt of Timer0 for this task.
    // So we need to activate it every time we want to start control algorithm
    #define REGULATION_START TIMSK0|=(1<<OCIE0A)
    #define REGULATION_STOP TIMSK0&=~(1<<OCIE0A)

    /*
     *  Timer1 for LCD redrawing (2.5 Hz) (CONFIRMED)
     */
    OCR1A = 12499;
    // Mode CTC on OCR1A, set prescaler to 256 and start the timer
    TCCR1B |= (1<<WGM12) | (1<<CS12);
    // We don't have dedicated routine for LCD processing as we use interrupt of Timer1 for this task.
    // So we need to enable interrupt every time when we want to constantly refreshing LCD. See
    // corresponding ISR for more details
    #define LCD_ROUTINE_ON TIMSK1|=(1<<OCIE1A)
    #define LCD_ROUTINE_OFF TIMSK1&=~(1<<OCIE1A)

    motor_init();

    adc_init();

    /*
     *  Handle bypass mode
     */
    if (eeprom_read_byte(&bypass_ON_flag_EEPROM)) {
        lcd.clear();
        lcd.print("regulation off");
    }
    else {
        // LCD timer ON
        LCD_ROUTINE_ON;
        // Plasm interrupt ON
        PCMSK0 |= (1<<PLASM_SIGNAL_INT);
    }

    // finally globally enable interrupts
    sei();

    while (1) {}
}



/*
 *  Interrupt handler for control algorithm timer
 */
ISR (TIMER0_COMPA_vect) {

    // measure voltage of the arc
    feedback = adc_read(ADC_FEEDBACK_PIN);

    // Define setpoint by measured values that staying in ±OFFSET_FOR_AVRG interval
    // (NUM_OF_VALUES_FOR_SETPOINT_DEFINITION values)
    if (setpoint_defined == false) {
        if (feedback_accum_cnt < NUM_OF_VALUES_FOR_SETPOINT_DEFINITION) {
            if (abs(feedback-feedback_prev) <= OFFSET_FOR_AVRG) {
                feedback_accum += feedback;
                feedback_accum_cnt++;
            }
        }
        else {
            setpoint_defined = true;
            // calculate setpoint
            setpoint = feedback_accum/NUM_OF_VALUES_FOR_SETPOINT_DEFINITION;

            feedback_accum = 0;
            feedback_accum_cnt = 0;

            sprintf(bufferA, "measured: %0.2fV", ADC_REFERENCE_VOLTAGE*setpoint/1023);
            lcd.clear();
            lcd.print(bufferA);

            menu = WORK_MENU;

            // Turn ON timer interrupt for LCD when setpoint is defined and main
            // regulation mode is started
            LCD_ROUTINE_ON;
        }
    }
    // setpoint defined
    else {
        // Same as above, we accumulate ADC values that close to each other
        // (±OFFSET_FOR_AVRG hysteresis interval)
        if (abs(feedback-feedback_prev) <= OFFSET_FOR_AVRG) {
            feedback_accum += feedback;
            feedback_accum_cnt++;
        }

        // We gather data at each ISR flash but process it only each
        // PRESCALER_MAIN_ALGO times
        if (++prescaler_cnt == PRESCALER_MAIN_ALGO) {
            prescaler_cnt = 0;

            feedback_avrg = feedback_accum/feedback_accum_cnt;
            feedback_accum = 0;
            feedback_accum_cnt = 0;

            // lift up if torch is too low (taking into account the hysteresis interval)
            if (feedback_avrg < (setpoint-setpoint_offset))
                motor_up();
            // get down if torch is too high (taking into account the hysteresis interval)
            else if (feedback_avrg > (setpoint+setpoint_offset))
                motor_down();
            // otherwise stop
            else
                motor_stop();
        }
    }

    // store previous value
    feedback_prev = feedback;
}



/*
 *  Interrupt handler for LCD menu timer
 */
ISR (TIMER1_COMPA_vect) {

    // if bypass mode ON
    if ( eeprom_read_byte(&bypass_ON_flag_EEPROM) ) {
        // turn off LCD timer interrupt (i.e. this interrupt)
        LCD_ROUTINE_OFF;
        return;
    }

    switch (menu) {

        // print only second row - current voltage (averaged)
        case WORK_MENU:
            sprintf(bufferB, "%0.2f", ADC_REFERENCE_VOLTAGE*feedback_avrg/1023);
            break;

        // print only once, then turn off LCD timer interrupt
        case IDLE_MENU:
            sprintf(bufferA, "sp: %0.2fV+-%3umV", ADC_REFERENCE_VOLTAGE*setpoint/1023,
                                                  (uint16_t)(1000*ADC_REFERENCE_VOLTAGE*setpoint_offset/1023));
            sprintf(bufferB, "lft%u dlay%u", cutting_height,
                                             pierce_time*PIERCE_TIME_ELEMENTARY_DELAY);
            lcd.clear();
            lcd.print(bufferA);
            // turn off LCD timer interrupt
            LCD_ROUTINE_OFF;
            break;

        // For the next 3 menu entries first string (bufferA) was printed outside this ISR
        // (at settings button ISR) so we only need to handle second row
        case cutting_height_MENU:
            // We don't map this, the default interval 0-1023 is OK for us
            // since ~200 steps is a one full revolution
            cutting_height = adc_read(ADC_SETTINGS_PIN);
            sprintf(bufferB, "%4u steps", cutting_height);
            break;

        case SETPOINT_OFFSET_MENU:
            setpoint_offset = map( adc_read(ADC_SETTINGS_PIN), 0, 1023,
                                   1023*SETPOINT_OFFSET_MIN_SET_VOLTAGE/ADC_REFERENCE_VOLTAGE,
                                   1023*SETPOINT_OFFSET_MAX_SET_VOLTAGE/ADC_REFERENCE_VOLTAGE  );
            sprintf(bufferB, "%3umV", (uint16_t)(1000*ADC_REFERENCE_VOLTAGE*setpoint_offset/1023));
            break;

        case PIERCE_TIME_MENU:
            pierce_time = map(adc_read(ADC_SETTINGS_PIN), 0, 1023, 0, PIERCE_TIME_MAX_TIME);
            sprintf(bufferB, "%5ums", pierce_time*PIERCE_TIME_ELEMENTARY_DELAY);
            break;
    }

    // we always print second row of LCD here
    lcd.setCursor(0, 1);
    lcd.print(bufferB);
}



/*
 *  Input signals interrupt
 */
ISR (PCINT0_vect) {

    // determine which bits have changed
    uint8_t changed_bits = SIGNALS_PIN ^ signals_port_history;
    // store current state as old one
    signals_port_history = SIGNALS_PIN;


    if ( changed_bits & (1<<SETTINGS_BUTTON_PIN) ) {
        // Anti-jitter delay. Button is pressed by a human so generally we need some
        // significant delay (also, the button quality is another one factor)
        _delay_ms(100);

        // HIGH to LOW pin change
        if ( !(SIGNALS_PIN & (1<<SETTINGS_BUTTON_PIN)) ) {

            // hold the button for about 7.5s to turn ON/OFF bypass mode (valid only from idle mode)
            uint8_t toggle_bypass_cnt = 0;
            while ( !(SIGNALS_PIN & (1<<SETTINGS_BUTTON_PIN)) && (menu==IDLE_MENU) ) {
                _delay_ms(100);
                if (++toggle_bypass_cnt > 75) {  // 75*100ms = 7.5s
                    toggle_bypass_cnt = 0;

                    // write status in EEPROM
                    eeprom_update_byte(&bypass_ON_flag_EEPROM, eeprom_read_byte(&bypass_ON_flag_EEPROM)^1);

                    // toggle plasm interrupt
                    PCMSK0 ^= (1<<PLASM_SIGNAL_INT);

                    lcd.clear();
                    lcd.print("regulation off");

                    // LCD timer interrupt ON
                    LCD_ROUTINE_ON;

                    return;
                }
            }
            // ignore short clicks in bypass mode
            if ( eeprom_read_byte(&bypass_ON_flag_EEPROM) ) return;


            /*
             *  Menu routine. We cycle through the menu entries and store
             *  the entered value from the previous menu (at each button press)
             */
            if (++menu == NUM_OF_MENUS)
                menu = IDLE_MENU;

            if (menu == IDLE_MENU) {
                // save previous parameter in EEPROM on button press
                eeprom_update_byte(&pierce_time_EEPROM, pierce_time);
                // turn on plasm interrupt only in Idle mode
                PCMSK0 |= (1<<PLASM_SIGNAL_INT);
            }
            else {
                // turn off plasm interrupt in settings mode
                PCMSK0 &= ~(1<<PLASM_SIGNAL_INT);

                if (menu == cutting_height_MENU) {
                    sprintf(bufferA, "lift (%u):", cutting_height);
                }
                else if (menu == SETPOINT_OFFSET_MENU) {
                    eeprom_update_word(&cutting_height_EEPROM, cutting_height);
                    sprintf(bufferA, "offset (%u):", (uint16_t)(1000*ADC_REFERENCE_VOLTAGE*setpoint_offset/1023));
                }
                else if (menu == PIERCE_TIME_MENU) {
                    eeprom_update_word(&setpoint_offset_EEPROM, setpoint_offset);
                    sprintf(bufferA, "delay (%u):", pierce_time*PIERCE_TIME_ELEMENTARY_DELAY);
                }

                lcd.clear();
                lcd.print(bufferA);
                // timer interrupt for LCD ON
                LCD_ROUTINE_ON;
            }
        }
    }


    // Note that it's important to use if-elseif construction because otherwise
    // we can fall to the strange and unpredicted behavior
    else if ( changed_bits & (1<<UP_SIGNAL_PIN) ) {
        if ( SIGNALS_PIN & (1<<UP_SIGNAL_PIN) )
            motor_stop();
        else
            motor_up();
    }


    else if ( changed_bits & (1<<DOWN_SIGNAL_PIN) ) {
        if ( SIGNALS_PIN & (1<<DOWN_SIGNAL_PIN) )
            motor_stop();
        else
            motor_down();
    }


    else if ( changed_bits & (1<<PLASM_SIGNAL_PIN) ) {
        // plasm relay cause jitter
        _delay_ms(20);

        // LOW to HIGH pin change (plasm is OFF)
        if ( SIGNALS_PIN & (1<<PLASM_SIGNAL_PIN) ) {
            // regulation OFF (imer interrupt for algorithm OFF)
            REGULATION_STOP;
            motor_stop();

            // reset variables
            prescaler_cnt = 0;
            feedback_accum = 0;
            feedback_accum_cnt = 0;
            feedback_avrg = 0;
            setpoint_defined = false;

            // interrupt for signals ON
            PCMSK0 |= (1<<SETTINGS_BUTTON_INT) | (1<<UP_SIGNAL_INT) | (1<<DOWN_SIGNAL_INT);
            // turn off touch tracking
            PCMSK0 &= ~(1<<TOUCH_SIGNAL_INT);

            // go to Idle mode
            menu = IDLE_MENU;

            // in case of interrupted regulation session Timer interrupt for LCD ON
            LCD_ROUTINE_ON;
        }

        // HIGH to LOW pin change (plasm is ON)
        else {
            // turn off touch tracking (do it only here to prevent any random triggering)
            PCMSK0 |= (1<<TOUCH_SIGNAL_INT);
            // interrupt OFF for all signals except PLASM_SIGNAL_PIN and TOUCH_SIGNAL_PIN
            PCMSK0 &= ~( (1<<SETTINGS_BUTTON_INT) | (1<<UP_SIGNAL_INT) | (1<<DOWN_SIGNAL_INT) );
            // move down till the torch touch the metal
            motor_down();

            lcd.clear();
            lcd.print("start...");
        }
    }


    else if ( changed_bits & (1<<TOUCH_SIGNAL_PIN) ) {

        // HIGH to LOW pin change
        if ( !(SIGNALS_PIN & (1<<TOUCH_SIGNAL_PIN)) ) {

            motor_stop();
            // turn off touch tracking
            PCMSK0 &= ~(1<<TOUCH_SIGNAL_INT);
            // lift to desired distance of cutting the metal
            motor_move(cutting_height);

            // Wait a bit for pierce (torch is fully burning and all metal droplets
            // can't affect the measurements)
            lcd.clear();
            lcd.print("pierce...");
            uint8_t pierce_time_cnt = pierce_time;
            do {
                _delay_ms(PIERCE_TIME_ELEMENTARY_DELAY);
            } while (--pierce_time_cnt);

            // If you see this, it means very noisy signal and/or too many points for setpoint definition
            // (NUM_OF_VALUES_FOR_SETPOINT_DEFINITION), and/or very small interval for averaging (OFFSET_FOR_AVRG)
            lcd.clear();
            lcd.print("define sp...");

            // timer interrupt for algorithm ON
            REGULATION_START;
        }
    }

}

Si c’est cette bibliothèque il faut appeler init() dans le setup comme montré dans les exemples.
https://github.com/johnrickman/LiquidCrystal_I2C/blob/738765e388816fb2a687d40436cd2604febce1b1/examples/HelloWorld/HelloWorld.pde#L8-L10

Le faites vous ? Est-ce que les exemples fonctionnent avec votre montage ?


Note: Lisez les recommandations listées dans « Les bonnes pratiques du Forum Francophone” pour poster et relisez vous, vos explications sont assez difficiles à lire à cause de la grammaire et de l’orthographe plus qu’approximatives…

Salut J-M-L,

Jai charger le program avec arduino ide, les branchement sont ok,
Mais cependant j'ai un peux de probleme a charger des des code en VScode pour les fair fonctionne :frowning:

Je sais pas si ceci peux t'aidé.

Mais oui les init() sont la

Salut.

Peut être un problème récurent sur ce forum ?
Régler le contraste de l'afficheur ... (petit potentiomètre bleu sur le module I2C)

Sinon, vérifier l'adresse I2C à l'aide de I2Cscanner.

cette bibliothèque est vieille et peut être pas optimale.

Le plus simple est d'utiliser la bibliothèque hd44780

et testez code

#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd;
const int nbCols = 20;
const int nbLignes = 4;

void setup() {
  
  Serial.begin(115200);

  int lcdAbsent = lcd.begin(nbCols, nbLignes);
  if (lcdAbsent) {
    Serial.print(" initialisation LCD - erreur ");
    Serial.println(lcdAbsent);
    hd44780::fatalError(lcdAbsent);
  }

  lcd.print("BONJOUR");

}

void loop() {}

si votre écran ne s'allume pas, soit il est mal branché, soit il a un souci de contraste, soit il est cassé.

(il faut bien sûr aussi mettre 5V et GND sur l'écran)

Écran fonctionne avec d'autre code pour le LCD

J'ai testé la configuration avec le hd44780 et toujours le meme problème rien affiche.

Il semble manque quelque chose mais je comprend mal :frowning:
ceci et le fichier modifier avec le hd44780 : TorchHeightControl.h

#ifndef TORCHHEIGHTCONTROL_H_
#define TORCHHEIGHTCONTROL_H_



/*
 *  Main libraries
 */
// already contains all necessary AVR's and C standard library functions
#include <Arduino.h>

/*
 *  User libraries
 */
// We use custom ADC library instead of Arduino's analogRead()
// because second takes some unwanted for us periphery (timer)
// and it is actually quite simple to write your own lightweight version
// of analogRead() so why not?
#include <ADC.h>
// Abstraction layer for the way we rule the motor. There can be a driver
// for a stepper motor plus set of switches, a stepper motor with
// "intelligent" step-direction driver, simply DC motor or whatever you wants to.
#include <MotorDriver.h>


/*
 *  Control signals definitions (all of them are inputs)
 *  Free (unused) pins:
 *    - PB5 (can be used as a test LED)
 *    - PD0
 *    - PD1
 */
#define SIGNALS_DDR DDRB
#define SIGNALS_PIN PINB
#define UP_SIGNAL_PIN PB2 // PIN 10
#define UP_SIGNAL_INT PCINT2
#define DOWN_SIGNAL_PIN PB3 //PIN 11
#define DOWN_SIGNAL_INT PCINT3
#define PLASM_SIGNAL_PIN PB4 //PIN 12
#define PLASM_SIGNAL_INT PCINT4
#define TOUCH_SIGNAL_PIN PB1 //PIN 9
#define TOUCH_SIGNAL_INT PCINT1
#define SETTINGS_BUTTON_PIN PB0 //PIN 8
#define SETTINGS_BUTTON_INT PCINT0
// initial state: all signals are pulled up to Vcc
uint8_t signals_port_history = 0xFF;


/*
 *  Menu definitions
 */
enum Menu {
    WORK_MENU,
    IDLE_MENU,
    cutting_height_MENU,
    SETPOINT_OFFSET_MENU,
    PIERCE_TIME_MENU,

    NUM_OF_MENUS
};
uint8_t menu = IDLE_MENU;  // initial state


/*
 *  LCD definitions. We use Arduino's standard library LiquidCrystal for this
 *  because of its robustness and widespread
 */
//#include <LiquidCrystal.h> // Enlever Louis
//#include <LiquidCrystal_I2C.h> //LG
#include <Wire.h>  // Teste LG
#include <hd44780.h>  // Teste LG
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header // Teste LG
hd44780_I2Cexp lcd; // auto detect backpack and pin mappin
// RS, RW (optional, faster in general), E, D4-7
//LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display //LG
//LiquidCrystal lcd(1, 2, 3, 4, 5, 6, 7); //EN LG 
// we need slightly more than the length of a string (16 in our case)
// due to the inner structure of the sprintf(). Otherwise, displayed
// values can be corrupted
#define BUFFER_SIZE 25
char bufferA[BUFFER_SIZE];  // 1st raw of LCD
char bufferB[BUFFER_SIZE];  // 2nd raw of LCD


/*
 *  LED for testing purposes. PB5 is built-in on UNO and NANO
 */
// #define TEST_LED
#ifdef TEST_LED
    #define TEST_LED_DDR DDRB
    #define TEST_LED_PORT PORTB
    #define TEST_LED_PIN PB5
#endif



#endif /* TORCHHEIGHTCONTROL_H_ */

En suite le code TorchHeightControl.cpp

#include <TorchHeightControl.h>



/*
 *  Other settings
 */
// Lift before cut is measured in steps of stepper motor (0-1023).
// EEMEM is the default value at the flash time. Actually, not so important
// because we always can change it at runtime
uint16_t cutting_height;  // cutting_height
uint16_t EEMEM cutting_height_EEPROM = 150;
// Pierce time is measured in ELEMENTARY_DELAYs which in turn is measured in ms
uint8_t pierce_time;
#define PIERCE_TIME_ELEMENTARY_DELAY 100  // 100 ms
#define PIERCE_TIME_MAX_TIME 50  // 50*ELEMENTARY_DELAY = 5s max
uint8_t EEMEM pierce_time_EEPROM = 20;  // 20*ELEMENTARY_DELAY = 2000ms
// Flag of the "bypass mode" without regulation. We explicitly use uint8_t type
// (instead of bool) because AVR's EEPROM driver has function for that
uint8_t EEMEM bypass_ON_flag_EEPROM = 0;


/*
 *  Setpoint settings
 */
uint16_t setpoint = 0;
// setpoint will be automatically defined at regulation start
#define NUM_OF_VALUES_FOR_SETPOINT_DEFINITION 200
bool setpoint_defined = false;
// hysteresis for control algorithm (setpoint ± setpoint_offset)
uint16_t setpoint_offset;
uint16_t EEMEM setpoint_offset_EEPROM = 20;  // 97mV
// interval of voltages for specifing setpoint offset in settings menus, Volts
#define SETPOINT_OFFSET_MIN_SET_VOLTAGE 0.010
#define SETPOINT_OFFSET_MAX_SET_VOLTAGE 0.200


/*
 *  Signal from arc and control algorithm definitions. Note that we use shared
 *  feedback variables first for setpoint defining and then for main regulation
 *  algorithm itself
 */
uint16_t feedback = 0;  // 10-bit ADC value
uint16_t feedback_prev = 0;  // previous ADC value
uint32_t feedback_accum = 0;  // accumulator for averaging
uint16_t feedback_accum_cnt = 0;  // counter of num of values for averaging
uint16_t feedback_avrg = 0;
// counter for manual dividing frequency of algo' timer in its ISR
uint8_t prescaler_cnt = 0;
#define PRESCALER_MAIN_ALGO 50
// hysteresis for averaging only close results of ADC measurements
#define OFFSET_FOR_AVRG 10  // ±48mV



int main(void) {

    // disable all interrupts while setup
    cli();

    /*
     *  Debug LED
     */
    #ifdef TEST_LED
        TEST_LED_DDR |= (1<<TEST_LED_PIN);
        TEST_LED_PORT &= ~(1<<TEST_LED_PIN);
    #endif

    /*
     * LCD startup
     */      
    lcd.init(); //AJ LG
    lcd.backlight(); // AJ LG
    lcd.begin(16, 2);
    lcd.clear();
    lcd.setCursor(0,0); //AJ LG
    lcd.print("loading...");
    delay(2000); //100 //AJ LG
    lcd.clear(); // AG LG

    /*
     *  Retrieve values from EEPROM
     */
    setpoint_offset = eeprom_read_word(&setpoint_offset_EEPROM);
    cutting_height = eeprom_read_word(&cutting_height_EEPROM);
    pierce_time = eeprom_read_byte(&pierce_time_EEPROM);

    /*
     *  Set directions of IOs
     */
    // outputs:
    // MOTOR_DDR |= (1<<MOTOR_PHASE_A)|(1<<MOTOR_PHASE_B)|(1<<MOTOR_PHASE_C)|(1<<MOTOR_PHASE_D);
    // inputs:
    SIGNALS_DDR &= ~( (1<<SETTINGS_BUTTON_PIN) | (1<<UP_SIGNAL_PIN) | (1<<DOWN_SIGNAL_PIN) |
                      (1<<PLASM_SIGNAL_PIN) | (1<<TOUCH_SIGNAL_PIN) );

    /*
     *  Interrupts setup (so far only for up, down and settings button pins)
     */
    PCICR |= (1<<PCIE0);
    PCMSK0 |= (1<<SETTINGS_BUTTON_INT) | (1<<UP_SIGNAL_INT) | (1<<DOWN_SIGNAL_INT);

    /*
     *  Timer0 for the torch height control algorithm
     */
    // CTC mode
    TCCR0A |= (1<<WGM01);
    // 1000 Hz frequency (formula from datasheet) (CONFIRMED). For getting actual frequency
    // of controlling divide this frequency on PRESCALER_MAIN_ALGO
    OCR0A = 124;
    // Set prescaler to 64 and start the timer
    TCCR0B |= (1<<CS01)|(1<<CS00);
    // We don't have dedicated controlling procedure as we use interrupt of Timer0 for this task.
    // So we need to activate it every time we want to start control algorithm
    #define REGULATION_START TIMSK0|=(1<<OCIE0A)
    #define REGULATION_STOP TIMSK0&=~(1<<OCIE0A)

    /*
     *  Timer1 for LCD redrawing (2.5 Hz) (CONFIRMED)
     */
    OCR1A = 12499;
    // Mode CTC on OCR1A, set prescaler to 256 and start the timer
    TCCR1B |= (1<<WGM12) | (1<<CS12);
    // We don't have dedicated routine for LCD processing as we use interrupt of Timer1 for this task.
    // So we need to enable interrupt every time when we want to constantly refreshing LCD. See
    // corresponding ISR for more details
    #define LCD_ROUTINE_ON TIMSK1|=(1<<OCIE1A)
    #define LCD_ROUTINE_OFF TIMSK1&=~(1<<OCIE1A)

    motor_init();

    adc_init();

    /*
     *  Handle bypass mode
     */
    if (eeprom_read_byte(&bypass_ON_flag_EEPROM)) {
        lcd.clear();
        lcd.print("regulation off");
    }
    else {
        // LCD timer ON
        LCD_ROUTINE_ON;
        // Plasm interrupt ON
        PCMSK0 |= (1<<PLASM_SIGNAL_INT);
    }

    // finally globally enable interrupts
    sei();

    while (1) {}
}



/*
 *  Interrupt handler for control algorithm timer
 */
ISR (TIMER0_COMPA_vect) {

    // measure voltage of the arc
    feedback = adc_read(ADC_FEEDBACK_PIN);

    // Define setpoint by measured values that staying in ±OFFSET_FOR_AVRG interval
    // (NUM_OF_VALUES_FOR_SETPOINT_DEFINITION values)
    if (setpoint_defined == false) {
        if (feedback_accum_cnt < NUM_OF_VALUES_FOR_SETPOINT_DEFINITION) {
            if (abs(feedback-feedback_prev) <= OFFSET_FOR_AVRG) {
                feedback_accum += feedback;
                feedback_accum_cnt++;
            }
        }
        else {
            setpoint_defined = true;
            // calculate setpoint
            setpoint = feedback_accum/NUM_OF_VALUES_FOR_SETPOINT_DEFINITION;

            feedback_accum = 0;
            feedback_accum_cnt = 0;

            sprintf(bufferA, "measured: %0.2fV", ADC_REFERENCE_VOLTAGE*setpoint/1023);
            lcd.clear();
            lcd.print(bufferA);

            menu = WORK_MENU;

            // Turn ON timer interrupt for LCD when setpoint is defined and main
            // regulation mode is started
            LCD_ROUTINE_ON;
        }
    }
    // setpoint defined
    else {
        // Same as above, we accumulate ADC values that close to each other
        // (±OFFSET_FOR_AVRG hysteresis interval)
        if (abs(feedback-feedback_prev) <= OFFSET_FOR_AVRG) {
            feedback_accum += feedback;
            feedback_accum_cnt++;
        }

        // We gather data at each ISR flash but process it only each
        // PRESCALER_MAIN_ALGO times
        if (++prescaler_cnt == PRESCALER_MAIN_ALGO) {
            prescaler_cnt = 0;

            feedback_avrg = feedback_accum/feedback_accum_cnt;
            feedback_accum = 0;
            feedback_accum_cnt = 0;

            // lift up if torch is too low (taking into account the hysteresis interval)
            if (feedback_avrg < (setpoint-setpoint_offset))
                motor_up();
            // get down if torch is too high (taking into account the hysteresis interval)
            else if (feedback_avrg > (setpoint+setpoint_offset))
                motor_down();
            // otherwise stop
            else
                motor_stop();
        }
    }

    // store previous value
    feedback_prev = feedback;
}



/*
 *  Interrupt handler for LCD menu timer
 */
ISR (TIMER1_COMPA_vect) {

    // if bypass mode ON
    if ( eeprom_read_byte(&bypass_ON_flag_EEPROM) ) {
        // turn off LCD timer interrupt (i.e. this interrupt)
        LCD_ROUTINE_OFF;
        return;
    }

    switch (menu) {

        // print only second row - current voltage (averaged)
        case WORK_MENU:
            sprintf(bufferB, "%0.2f", ADC_REFERENCE_VOLTAGE*feedback_avrg/1023);
            break;

        // print only once, then turn off LCD timer interrupt
        case IDLE_MENU:
            sprintf(bufferA, "sp: %0.2fV+-%3umV", ADC_REFERENCE_VOLTAGE*setpoint/1023,
                                                  (uint16_t)(1000*ADC_REFERENCE_VOLTAGE*setpoint_offset/1023));
            sprintf(bufferB, "lft%u dlay%u", cutting_height,
                                             pierce_time*PIERCE_TIME_ELEMENTARY_DELAY);
            lcd.clear();
            lcd.print(bufferA);
            // turn off LCD timer interrupt
            LCD_ROUTINE_OFF;
            break;

        // For the next 3 menu entries first string (bufferA) was printed outside this ISR
        // (at settings button ISR) so we only need to handle second row
        case cutting_height_MENU:
            // We don't map this, the default interval 0-1023 is OK for us
            // since ~200 steps is a one full revolution
            cutting_height = adc_read(ADC_SETTINGS_PIN);
            sprintf(bufferB, "%4u steps", cutting_height);
            break;

        case SETPOINT_OFFSET_MENU:
            setpoint_offset = map( adc_read(ADC_SETTINGS_PIN), 0, 1023,
                                   1023*SETPOINT_OFFSET_MIN_SET_VOLTAGE/ADC_REFERENCE_VOLTAGE,
                                   1023*SETPOINT_OFFSET_MAX_SET_VOLTAGE/ADC_REFERENCE_VOLTAGE  );
            sprintf(bufferB, "%3umV", (uint16_t)(1000*ADC_REFERENCE_VOLTAGE*setpoint_offset/1023));
            break;

        case PIERCE_TIME_MENU:
            pierce_time = map(adc_read(ADC_SETTINGS_PIN), 0, 1023, 0, PIERCE_TIME_MAX_TIME);
            sprintf(bufferB, "%5ums", pierce_time*PIERCE_TIME_ELEMENTARY_DELAY);
            break;
    }

    // we always print second row of LCD here
    lcd.setCursor(0, 1);
    lcd.print(bufferB);
}



/*
 *  Input signals interrupt
 */
ISR (PCINT0_vect) {

    // determine which bits have changed
    uint8_t changed_bits = SIGNALS_PIN ^ signals_port_history;
    // store current state as old one
    signals_port_history = SIGNALS_PIN;


    if ( changed_bits & (1<<SETTINGS_BUTTON_PIN) ) {
        // Anti-jitter delay. Button is pressed by a human so generally we need some
        // significant delay (also, the button quality is another one factor)
        _delay_ms(100);

        // HIGH to LOW pin change
        if ( !(SIGNALS_PIN & (1<<SETTINGS_BUTTON_PIN)) ) {

            // hold the button for about 7.5s to turn ON/OFF bypass mode (valid only from idle mode)
            uint8_t toggle_bypass_cnt = 0;
            while ( !(SIGNALS_PIN & (1<<SETTINGS_BUTTON_PIN)) && (menu==IDLE_MENU) ) {
                _delay_ms(100);
                if (++toggle_bypass_cnt > 75) {  // 75*100ms = 7.5s
                    toggle_bypass_cnt = 0;

                    // write status in EEPROM
                    eeprom_update_byte(&bypass_ON_flag_EEPROM, eeprom_read_byte(&bypass_ON_flag_EEPROM)^1);

                    // toggle plasm interrupt
                    PCMSK0 ^= (1<<PLASM_SIGNAL_INT);

                    lcd.clear();
                    lcd.print("regulation off");

                    // LCD timer interrupt ON
                    LCD_ROUTINE_ON;

                    return;
                }
            }
            // ignore short clicks in bypass mode
            if ( eeprom_read_byte(&bypass_ON_flag_EEPROM) ) return;


            /*
             *  Menu routine. We cycle through the menu entries and store
             *  the entered value from the previous menu (at each button press)
             */
            if (++menu == NUM_OF_MENUS)
                menu = IDLE_MENU;

            if (menu == IDLE_MENU) {
                // save previous parameter in EEPROM on button press
                eeprom_update_byte(&pierce_time_EEPROM, pierce_time);
                // turn on plasm interrupt only in Idle mode
                PCMSK0 |= (1<<PLASM_SIGNAL_INT);
            }
            else {
                // turn off plasm interrupt in settings mode
                PCMSK0 &= ~(1<<PLASM_SIGNAL_INT);

                if (menu == cutting_height_MENU) {
                    sprintf(bufferA, "lift (%u):", cutting_height);
                }
                else if (menu == SETPOINT_OFFSET_MENU) {
                    eeprom_update_word(&cutting_height_EEPROM, cutting_height);
                    sprintf(bufferA, "offset (%u):", (uint16_t)(1000*ADC_REFERENCE_VOLTAGE*setpoint_offset/1023));
                }
                else if (menu == PIERCE_TIME_MENU) {
                    eeprom_update_word(&setpoint_offset_EEPROM, setpoint_offset);
                    sprintf(bufferA, "delay (%u):", pierce_time*PIERCE_TIME_ELEMENTARY_DELAY);
                }

                lcd.clear();
                lcd.print(bufferA);
                // timer interrupt for LCD ON
                LCD_ROUTINE_ON;
            }
        }
    }


    // Note that it's important to use if-elseif construction because otherwise
    // we can fall to the strange and unpredicted behavior
    else if ( changed_bits & (1<<UP_SIGNAL_PIN) ) {
        if ( SIGNALS_PIN & (1<<UP_SIGNAL_PIN) )
            motor_stop();
        else
            motor_up();
    }


    else if ( changed_bits & (1<<DOWN_SIGNAL_PIN) ) {
        if ( SIGNALS_PIN & (1<<DOWN_SIGNAL_PIN) )
            motor_stop();
        else
            motor_down();
    }


    else if ( changed_bits & (1<<PLASM_SIGNAL_PIN) ) {
        // plasm relay cause jitter
        _delay_ms(20);

        // LOW to HIGH pin change (plasm is OFF)
        if ( SIGNALS_PIN & (1<<PLASM_SIGNAL_PIN) ) {
            // regulation OFF (imer interrupt for algorithm OFF)
            REGULATION_STOP;
            motor_stop();

            // reset variables
            prescaler_cnt = 0;
            feedback_accum = 0;
            feedback_accum_cnt = 0;
            feedback_avrg = 0;
            setpoint_defined = false;

            // interrupt for signals ON
            PCMSK0 |= (1<<SETTINGS_BUTTON_INT) | (1<<UP_SIGNAL_INT) | (1<<DOWN_SIGNAL_INT);
            // turn off touch tracking
            PCMSK0 &= ~(1<<TOUCH_SIGNAL_INT);

            // go to Idle mode
            menu = IDLE_MENU;

            // in case of interrupted regulation session Timer interrupt for LCD ON
            LCD_ROUTINE_ON;
        }

        // HIGH to LOW pin change (plasm is ON)
        else {
            // turn off touch tracking (do it only here to prevent any random triggering)
            PCMSK0 |= (1<<TOUCH_SIGNAL_INT);
            // interrupt OFF for all signals except PLASM_SIGNAL_PIN and TOUCH_SIGNAL_PIN
            PCMSK0 &= ~( (1<<SETTINGS_BUTTON_INT) | (1<<UP_SIGNAL_INT) | (1<<DOWN_SIGNAL_INT) );
            // move down till the torch touch the metal
            motor_down();

            lcd.clear();
            lcd.print("start...");
        }
    }


    else if ( changed_bits & (1<<TOUCH_SIGNAL_PIN) ) {

        // HIGH to LOW pin change
        if ( !(SIGNALS_PIN & (1<<TOUCH_SIGNAL_PIN)) ) {

            motor_stop();
            // turn off touch tracking
            PCMSK0 &= ~(1<<TOUCH_SIGNAL_INT);
            // lift to desired distance of cutting the metal
            motor_move(cutting_height);

            // Wait a bit for pierce (torch is fully burning and all metal droplets
            // can't affect the measurements)
            lcd.clear();
            lcd.print("pierce...");
            uint8_t pierce_time_cnt = pierce_time;
            do {
                _delay_ms(PIERCE_TIME_ELEMENTARY_DELAY);
            } while (--pierce_time_cnt);

            // If you see this, it means very noisy signal and/or too many points for setpoint definition
            // (NUM_OF_VALUES_FOR_SETPOINT_DEFINITION), and/or very small interval for averaging (OFFSET_FOR_AVRG)
            lcd.clear();
            lcd.print("define sp...");

            // timer interrupt for algorithm ON
            REGULATION_START;
        }
    }

}

Si le test qui dit bonjour ne fonctionne pas, il n’y a aucune chance pour qu’un code plus complet ne fonctionne

Le teste qui dit bonjours fonctionne tres bien.
Alors jai essayer d'incorporer les information du code bonjours dans mon code mais la rien affiche.

Il doit surment me.manquer quelque chose pour faire activer mon ecran

Postez tout le code avec la bibliothèque intégrée

Salut J-M-L

Voici ce que j'ai fait a date dans le projet

lien Wetransfere : https://we.tl/t-ySQ3nviaic Il sera disponible 7jours de memoir.

pour toute question je reste disponible :slight_smile:

Merci !

postez le code ici avec les balises de code

Bien cest ce que jai fait avant non ?
Sinon je ne comprend pas :frowning:
Je tes toute mit le code que jai a jouer avec les autre son de library.
Sinon donne moi une exemple

je veux dire postez ici, je lis sur mon iPhone, je ne vais pas aller sur Wetransfer..

Ok mais les balise de code son en haut avec l'ajustement suite a la librairi de l'ecran hd44780.

Je ne sais pas vous donner de plus :thinking:

Sinon vous avez toute mon projet dans le lien wetransfere avec toute les info nécessaires .

Je pense que @J-M-L pense que si tu donne un lien vers ton code, c'est qu'il y a une différence avec celui poster en début de ton post.
Surtout que tu indique que c'est ce que tu fait à date.

En général sauf si tu le précise expressément, on ne regarde pas si tu change ton code précédemment posté.

Bonjour,

Bon je pense que ceci sera ok pour vous ?
J'ai toute charger sur Github : https://github.com/Lgagnon43/LG-THC

Le tous est la. au plaisir ! :slight_smile:

Il manque la bibliothèque pour le lcd dans ton code sur GitHub.

Git hub ne veulent pas que je load vu que le fichier et trop gros Mais c'est la bibliothèque hd44780 de bill perry.

La bibliothèque n'est pas déclarée dans ton code.