Home Forums Search Search Results for 'oled'

Viewing 15 results - 1 through 15 (of 23 total)
  • Author
    Search Results
  • #31970
    MAWMN
    Participant

      Still Struggeling..

      Trying to reconfig SDA & SCL to NON Default pins on ESP32-CAM AI-Thinker board, NOT Working for PCF8574 Library, does work at the same time for U8g2 Library ?
      
      gives problems with the PCF8574 while the SSD display works fine with it: 
      Monitoring loop Started..
      Init pcf8574...OK
      but after constantly changing the content of the display (Seconds wise), all interrupts of the PCF8574 give :
      [ 55886][E][Wire.cpp:513] requestFrom(): i2cRead returned Error 263 
      
      #include <Arduino.h>
      #include <stdint.h>
      #include <esp_camera.h>
      
      //* for I2C
      #include <Wire.h> 
      TwoWire I2C_PINS_NON_DEFAULT = Wire;   // Try to reconfig the wire Lib to use NON Default Pins
      
      #define SCL 15                         // IO15  GPIO15  HSPI_WSO  HS2_CMD     SD-Conn
      #define SDA 14                         // IO14  GPIO14  HSPI_CLK  HS2_CLK     SD-Conn
      
      #define SETBUSSPEED                    // We do want to set the BusSpeed
      #undef SETBUSSPEED                     // We do NOT want to set the BusSpeed
      
      #ifdef SETBUSSPEED
        #define BUSSPEED 100000U             // BusSpeed = 100.000 kHz
        // #define BUSSPEED 400000U             // BusSpeed = 400.000 kHz
      #endif
      
      //* SDD1306 Config
      #include <U8x8lib.h>    // I2C (Maximum Speed SCL +/- 400 kHz)                                      // ! Text Only Library
      U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // ! Text Only (from long list)
      
      //* PCF8574 MultiClick
      #include "PCF8574.h"
      #define PCF_INTERRUPT 0				         // IO0   GPIO0   CAM_PIN_XCLK or CSI_MCLK (Interrupt pin for Encoder & Switch)
      
      // * RotaryEncoder defines (Connected to PCF8574)
      #define encoderPinA  			P0
      #define encoderPinB  			P1
      #define switchPin					P2
      
      // Forward declaration for the Interrupt (See Initialisation of isr_updateEncoder ISR Below), 
      //   necessary here because of the Interrupt Initialisation in the next Line
      void IRAM_ATTR isr_updateEncoder();	
      
      // Initialize PCF-library for used address, SDA & SCL, Interrupt function
      PCF8574 pcf8574(0x38, SDA, SCL, PCF_INTERRUPT, isr_updateEncoder);
        
      
      void IRAM_ATTR isr_updateEncoder() {
        //! DO NOT Read pcf8574.readEncoderValue(encoderPinA, encoderPinB, &encoderValue);
        //!         and pcf8574.digitalRead(switchPin); in the isr_updateEncoder() function here !!!
        //!  this will cause "Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1)"
        //!  Keep the interrupt function as short as possible and only set a flag here !!!
        //!  Next in the main loop() DO Read these values by the function getEncValues() and checkButton() !!!
        changed = true;
      }
      
      void ClrScr() {
        // ! *** See : https://github.com/olikraus/u8g2/wiki/u8x8reference
        u8x8.clear();
        delay(50);
        u8x8.clearDisplay();
        delay(50);
        u8x8.setFont(u8x8_font_chroma48medium8_r);      // Normal=1, Larger=2, largest=3, :1 pixel scale
        delay(50);                                      // See : https://github.com/olikraus/u8g2/wiki/fntlist8x8
        u8x8.print("");                                 // Draw text
        delay(50);
        u8x8.flush();
        delay(50);
      }
      
      void Display_Init() {    // ! *** Text Only
        u8x8.begin();                               // Start the Display Object, with NO PowerSaving
        delay(250);                                 // ! *** Extended delay 50 ==> 250 : See datasheet 18-12-2023 page 18 & 32
        u8x8.initDisplay();
        delay(50);         
        u8x8.setPowerSave(0);                       // Seems essentieel, for correct new start !!!
        delay(50);
        ClrScr();
      }
      
      void Display_Text(byte XPos, byte YPos, bool Invert, byte FieldSize, String MyText) {
        // u8x8 library only has LineMode (TEXT Only), for graphics use u8g2 library !!!
        // ! *** When using Graphics we are adressing X and y at pixel level !!!
        // ! *** When using Text Only we are adressing X and y at line level !!!
        // Set Font
        u8x8.setFont(u8x8_font_chroma48medium8_r);    // Small FontSize - 16 char/line
                                                      // See : https://github.com/olikraus/u8g2/wiki/fntlist8x8
      
        // Set Normal / Inverse
        if (Invert == false) {
          u8x8.setInverseFont(0);                     // Draw 'normal' text
        } else {
          u8x8.setInverseFont(1);                     // Draw 'inverse' text
        }
      
        String NewStr = MyText; // Set for when FieldSize is set to 0 (NO Size Control) OR Correct !!!
        if (FieldSize != 0) {
          // Control the Length of the Text Field
          if (MyText.length() > FieldSize) {
            // MyText too long
            NewStr = "";
            for (size_t i = 1; i < FieldSize; i++) NewStr = NewStr + MyText[i];
          }
      
          if (MyText.length() < FieldSize) {
            // MyText too short
            NewStr = MyText;
            while (NewStr.length() < FieldSize) NewStr = NewStr + " ";
          }
        }
        u8x8.drawString(XPos, YPos, NewStr.c_str());
        u8x8.flush();
      }
      
      void setup() {
        //* Init Serial
        Serial.begin(115200);
        delay(3000);              //! We Need at least 3 seconds to start up the serial port for monitoring @ ESP32-Cam in PlatformIO !!!
      
        I2C_PINS_NON_DEFAULT.begin(SDA, SCL);
      
        //* Init OLED-Display
        Display_Init();           // Initialize the display and Start Showing the Information
      
        // Show texts @ the SSD Display
        mText = "Config.Finished.";
        Display_Text(0, 1, false, 16, mText);
      
        mText = "M.A.W.M. Nijland";
        Display_Text(0, 3, false, 16, mText);
      
        mText = "Apeldoorn - 2024";
        Display_Text(0, 5, false, 16, mText);
      
        Serial.println("\nMonitoring loop Started..");
        Serial.flush();
      
        //* Initialize ESP-CAM Interrupt Input
        pinMode(PCF_INTERRUPT, INPUT_PULLUP);
      
      	//* Init PCF8574 pins	
        pcf8574.pinMode(encoderPinA, INPUT_PULLUP);   // Encoder A
        pcf8574.pinMode(encoderPinB, INPUT_PULLUP);   // Encoder B
      
      	// Encoder pins
      	pcf8574.encoder(encoderPinA, encoderPinB);
      
      	// Encoder button
      	pcf8574.pinMode(switchPin, INPUT_PULLUP);
      
        delay(100);
      
      	// Start the PCF8574 library
      	Serial.print("Init pcf8574...");
      	if (pcf8574.begin(0x38)) {
      		// Board/Chip is Acknowledging the I2C Commands
      		Serial.println("OK");
      	} else {
      		// Board/Chip is NOT Acknowledging the I2C Commands
      		Serial.println("NOT OK");
      	}
      }
      
      loop() {
        // etc. etc..
      }
      #29327

      In reply to: module hang-up e220

      L33t331
      Participant

        There is nothing particularly interesting there, sending structures and output to oled.
        For now, I’m just testing how it will work for 7 days without any problems – I’ll share it!
        I am currently working on a small filter, otherwise noise in the data sometimes arrives.
        I also want to test the declared operating temperatures in the climate chamber (including up to -40 degrees) while searching for this camera in my city, as soon as I collect all the information, I can unsubscribe and share!)

        #29295

        In reply to: module hang-up e220

        L33t331
        Participant

          Hello, friend! I had the same assumptions about memory, but for some reason I discarded them, thinking that it was definitely not memory.
          now the module is stuck for 18 hours of operation, the data does not reach it, the past value is = nan.
          and there are two manual commands:
          lora.begin – re-initialization
          of serial2.flush.
          if they don’t help, I’ll watch the memory.
          do I understand correctly that you are talking about free esp memory? tell me the command to watch it, and I won’t make a mistake, I’ll display this value on the OLED screen, and leave the modules on for a day again.

          #29287
          L33t331
          Participant

            Hi, I’m not really friends with English, but I think you’ll understand me.

            I purchased three e220-900t22d modules to replace nrf24, because nrf does not work at temperatures below -6 degrees according to tests, it cannot send messages, and this is critical for me, because temperatures sometimes reach -40.

            And so I took the modules for the test, both are on esp 32, 915 frequency, serial 2, aux is connected, resistors are installed on tx,rx,aux, everything is as per the documentation, m0,m1 to gnd.
            The settings that I changed from the standard ones:
            -RSI_AMBIENT_NOISE_ENABLED
            -RSSI_ENABLED
            -LBT_ENABLED
            That is, I didn’t have any problems with the setup and everything else, thanks by the way for the library and a detailed description of everything!

            And so let’s move on to the problem.
            one esp 32,lora,ds18b20 module stands on the balcony and sends an array of data: temperature, minimum, maximum, operating time, etc.
            The other module is in a room with an oled screen, there is a maximum of two meters and a wall between them, there are no problems in data transmission, they communicate with each other in the period from 8-16 seconds to each other and vice versa send messages, it already works at -18 degrees, which is great.

            The problem itself is that the modules hang for the second time at 17 o’clock, (yesterday and today) today – exactly 17 hours of work came from the balcony module, while the esp32 themselves do not hang, they continue to work and count the time, etc., the module freezes, the values “nan” come to the module and it no longer accepts messages.
            -I come home from work and see that messages have not been received for 7 hours (a timer is prescribed), and there is an indication of esp operation, the last working time of the module from the balcony received by radio is 17 hours., I assume that the serial2 buffer is overloaded, because after restarting the room module, messages start coming from another, and it came that the working time of the balcony is 24 hours, which is correct and means that the balcony did not hang, just the room did not accept information, after restarting the room data to the room – they come, but they do not go to the balcony, after restarting the balcony, the data begins to reach the balcony.

            woto
            Participant

              Hello,
              I have a transmitter (ADDL = 2) with AVR ATTiny16 (like Arduino) and a receiver (ADDL = 1) with Raspberry Pi Pico.

              The transmitter sends a string every 6 seconds. Unfortunately, the Rasperry Pi Pico (receiver) does not receive the string.
              Yesterday it still worked, now it doesn’t and I don’t know what the reason could be.
              I suspect that the Pico has a problem. The transmitter and receiver are next to each other.

              I have connected an OLED to display the configuration.

              Here is the code for the transmitter:

              
              #define FREQUENCY_868
              #define ENABLE_RSSI true
              #define ACTIVATE_SOFTWARE_SERIAL
              // With FIXED SENDER configuration
              
              #define DESTINATION_ADDL 0x01
              #define OWN_ADDH 0x00
              #define OWN_ADDL 0x02
              
              #include
              #include
              
              #define txE220pin 4 //7 //Pull-Up Output
              #define rxE220pin 6 //Pull-Up Input
              #define auxPin 16 // Pull-Up Output
              #define m0Pin 3
              #define m1Pin 2
              
              // Start LoraWan-Config
              LoRa_E220 e220ttl(txE220pin, rxE220pin, auxPin, m0Pin, m1Pin); // e22 TX e22 RX
              
              //void printParameters(struct Configuration configuration);
              //void printModuleInformation(struct ModuleInformation moduleInformation);
              int i = 0;
              
              void setup() {
              oled.begin(128, 64, sizeof(tiny4koled_init_128x64), tiny4koled_init_128x64);
              oled.setRotation(1);
              
              // Two fonts are supplied with this library, FONT8X16 and FONT6X8
              // Other fonts are available from the TinyOLED-Fonts library
              oled.setFont(FONT6X8);
              
              // Clear the memory before turning on the display
              oled.clear();
              
              // Turn on the display
              oled.on();
              
              e220ttl.begin();
              
              delay(50);
              
              ResponseStructContainer c;
              c = e220ttl.getConfiguration();
              Configuration configuration = *(Configuration*) c.data;
              
              configuration.ADDL = OWN_ADDL;
              configuration.ADDH = OWN_ADDH;
              configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED;
              configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
              configuration.CRYPT.CRYPT_H = 0x01;
              configuration.CRYPT.CRYPT_L = 0x01;
              configuration.CHAN = 18;
              configuration.OPTION.transmissionPower = POWER_22; // Device power
              configuration.SPED.uartBaudRate = UART_BPS_9600; //UART_BPS_57600; // Serial baud rate
              
              e220ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_SAVE);
              
              ResponseStructContainer c1;
              c1 = e220ttl.getConfiguration();
              Configuration configuration1 = *(Configuration*) c1.data;
              
              oled.println(String (c1.status.getResponseDescription()));
              oled.println(String (configuration1.SPED.getUARTBaudRateDescription()));
              oled.println(String (configuration1.OPTION.getTransmissionPowerDescription()));
              oled.println(String (configuration1.getChannelDescription()));
              oled.println(String (configuration1.TRANSMISSION_MODE.getRSSIEnableByteDescription()));
              c.close();
              c1.close();
              
              // Send message
              ResponseStatus rs = e220ttl.sendFixedMessage(0, DESTINATION_ADDL, 18, String (OWN_ADDH) + String (OWN_ADDL) + ",Hello, world?");
              // Check If there is some problem of succesfully send
              oled.println("SendData: " + String (rs.getResponseDescription()));
              }
              
              void loop() {
              // put your main code here, to run repeatedly:
              ++i;
              // If something available
              if (e220ttl.available()>1) {
              // read the String message
              #ifdef ENABLE_RSSI
              ResponseContainer rc = e220ttl.receiveMessageRSSI();
              #else
              ResponseContainer rc = e220ttl.receiveMessage();
              #endif
              // Is something goes wrong print error
              if (rc.status.code!=1){
              oled.println(String (rc.status.getResponseDescription()));
              }else{
              // Print the data received
              oled.println(String (rc.status.getResponseDescription()));
              oled.println(String (rc.data));
              #ifdef ENABLE_RSSI
              oled.println("RSSI: " + String (rc.rssi));
              #endif
              }
              }
              delay(6000);
              ResponseStatus rs = e220ttl.sendFixedMessage(0, DESTINATION_ADDL, 18, String (OWN_ADDH) + String (OWN_ADDL) + ",Hello, world?" + String (i));
              oled.clear();
              oled.println("DESTINATION_ADDL: " + String (DESTINATION_ADDL));
              oled.println("SendData " + String (i) + " : " + String (rs.getResponseDescription()));
              }

              And here is the code for the receiver:

              # Author: Renzo Mischianti
              # Website: www.mischianti.org
              #
              # Description:
              # This script demonstrates how to use the E220 LoRa module with MicroPython.
              # It includes examples of sending and receiving string using both transparent and fixed transmission modes.
              # The code also configures the module's address and channel for fixed transmission mode.
              # Address and channel of this receiver:
              # ADDH = 0x00
              # ADDL = 0x01
              # CHAN = 23
              #
              # Can be used with the send_fixed_string and send_transparent_string scripts
              #
              # Note: This code was written and tested using MicroPython on an ESP32 board.
              # It works with other boards, but you may need to change the UART pins.
              
              import machine
              from time import sleep
              from umqtt.robust import MQTTClient
              from machine import UART, Pin
              import utime
              import network
              import time
              
              from LoraWanE220.lora_e220 import LoRaE220, Configuration, print_configuration
              from LoraWanE220.lora_e220_operation_constant import ResponseStatusCode
              from LoraWanE220.lora_e220_constants import FixedTransmission, RssiEnableByte
              
              # LORA-Konfiguration
              OWN_ADDH = 0x00
              OWN_ADDL = 0x01 # Adresse 1
              CHANNEL = 18 # 868Mhz
              
              # Initialize the LoRaE220 module
              uart1 = UART(1, rx=Pin(5), tx=Pin(4))
              lora = LoRaE220('900T22D', uart1, aux_pin=2, m0_pin=10, m1_pin=11)
              code = lora.begin()
              print("Initialization: {}", ResponseStatusCode.get_description(code))
              
              # Set the configuration to default values and print the updated configuration to the console
              # Not needed if already configured
              configuration_to_set = Configuration('900T22D')
              configuration_to_set.ADDH = OWN_ADDH # Address of this receive no sender
              configuration_to_set.ADDL = OWN_ADDL # Address of this receive no sender
              configuration_to_set.CHAN = CHANNEL # Address of this receive no sender
              configuration_to_set.TRANSMISSION_MODE.fixedTransmission = FixedTransmission.FIXED_TRANSMISSION
              # To enable RSSI, you must also enable RSSI on sender
              configuration_to_set.TRANSMISSION_MODE.enableRSSI = RssiEnableByte.RSSI_ENABLED
              # Enable Encryption
              configuration_to_set.CRYPT.CRYPT_H = 0x01;
              configuration_to_set.CRYPT.CRYPT_L = 0x01;
              
              code, confSetted = lora.set_configuration(configuration_to_set)
              print("Set configuration: {}", ResponseStatusCode.get_description(code))
              
              print_configuration(confSetted)
              
              print("Waiting for messages...")
              
              while True:
              if lora.available() > 0:
              # If the sender not set RSSI
              # code, value = lora.receive_message()
              # If the sender set RSSI
              code, value, rssi = lora.receive_message(rssi=True)
              #print('RSSI: ', rssi)
              
              #print(ResponseStatusCode.get_description(code))
              
              print(value)
              client.publish(topic, value)
              utime.sleep_ms(2000)
              
              client.disconnect()
              

              Maybe someone can find the error.

              Supachokhansaran
              Participant

                Hello Mr. Renzo, please help me.
                My name is Hansaran, and I have interest in electronics. I often read your articles about LoRa. I’m a beginner with LoRa and ESP32 modules, because usually I use Arduino for my projects.

                I want to create a LoRa communication device to monitor someone. The monitoring data will be sent to a gateway using the LoRa E220 module. I have never used LoRa before. I’m making this device to monitor my father, who is a sulfur miner. The mining is done manually, and there is no communication network available, which makes me worry about his condition. I hope this device can be completed and can be useful for my father. Sorry for the long explanation.

                When I try to integrate the “sendfixedtransmission” example into my existing program, I have an error like this.

                Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
                Core  1 register dump:
                PC      : 0x400d632b  PS      : 0x00060a30  A0      : 0x800d6413  A1      : 0x3ffc5b70  
                A2      : 0x3ffc2044  A3      : 0x000000c1  A4      : 0x00000000  A5      : 0x00000008  
                A6      : 0x3ffb7c80  A7      : 0x00000000  A8      : 0x800d6304  A9      : 0x3ffc5b60  
                A10     : 0x00000000  A11     : 0x000003e8  A12     : 0x00000064  A13     : 0x00000067  
                A14     : 0x00060a20  A15     : 0x00000001  SAR     : 0x0000000a  EXCCAUSE: 0x0000001c  
                EXCVADDR: 0x00000000  LBEG    : 0x4008474d  LEND    : 0x40084755  LCOUNT  : 0x00000027  
                
                Backtrace: 0x400d6328:0x3ffc5b70 0x400d6410:0x3ffc5ba0 0x400d2ba6:0x3ffc5be0 0x400d8b0a:0x3ffc5c40
                ELF file SHA256: 31e1dff54c44b265
                Rebooting...

                I’ve read articles about this error but still don’t understand it. https://stackoverflow.com/questions/63399901/how-to-fix-guru-meditation-error-core-1-paniced-loadprohibited-error

                It turned out that the buffer(declared globally) that I used for receiving messages was appending new messages instead of overwriting the pre-existing contents in it. So, an illegal memory-write attempt was made and the device panicked and rebooted.

                I’ve tried sending the fixed transmission example before and it worked.
                Please, I need your help.

                Here is my code:

                #include "U8g2lib.h"
                #include <Wire.h>
                #include "RTClib.h"
                #include "FS.h"
                #include "SD.h"
                #include "SPI.h"
                #include "Arduino.h"
                #include "LoRa_E220.h"
                
                U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0); // //OLED SSD1306 128x64
                LoRa_E220 e220ttl(&Serial2, 15, 33, 32); //  RX AUX M0 M1
                
                // 'icon_sync', 16x16px
                const unsigned char bitmap_icon_sinkronisasi [] PROGMEM = {
                  0x00, 0x00, 0xe0, 0x01, 0x10, 0x38, 0x88, 0x18, 0x84, 0x28, 0x82, 0x20, 0x82, 0x40, 0x82, 0x40,
                  0xc2, 0x4f, 0xc2, 0x40, 0x02, 0x40, 0x0a, 0x20, 0x0c, 0x10, 0x0e, 0x08, 0xc0, 0x07, 0x00, 0x00,
                };
                // 'icon_gps1', 16x16px
                const unsigned char bitmap_icon_node_sensor_1 [] PROGMEM = {
                  0x00, 0x00, 0xc0, 0x0f, 0x00, 0x10, 0x80, 0x27, 0x00, 0x48, 0x00, 0x53, 0x60, 0x54, 0xe0, 0x54,
                  0xe0, 0x51, 0xe0, 0x03, 0xe0, 0x03, 0x50, 0x40, 0xf8, 0x60, 0x04, 0x41, 0xfe, 0x43, 0x02, 0xe2,
                };
                // 'icon_gps2', 16x16px
                const unsigned char bitmap_icon_node_sensor_2 [] PROGMEM = {
                  0x00, 0x00, 0xc0, 0x0f, 0x00, 0x10, 0x80, 0x27, 0x00, 0x48, 0x00, 0x53, 0x60, 0x54, 0xe0, 0x54,
                  0xe0, 0x51, 0xe0, 0x03, 0xe0, 0x03, 0x50, 0x60, 0xf8, 0x90, 0x04, 0x41, 0xfe, 0x23, 0x02, 0xf2,
                };
                // 'icon kembang api', 16x16px
                const unsigned char bitmap_icon_sleep [] PROGMEM = {
                  0x00, 0x00, 0x00, 0x10, 0x00, 0x29, 0x08, 0x10, 0x08, 0x00, 0x36, 0x00,
                  0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x08,
                  0x20, 0x08, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00,
                };
                // 'icon jam', 16x16px
                const unsigned char bitmap_icon_set_waktu [] PROGMEM = {
                  0xe0, 0x07, 0x18, 0x18, 0x84, 0x24, 0x8a, 0x40, 0x82, 0x50, 0x81, 0x80, 0xc1, 0x81, 0x45, 0xae,
                  0x41, 0x82, 0x81, 0x81, 0x05, 0xa0, 0x02, 0x40, 0x12, 0x48, 0x04, 0x21, 0x18, 0x18, 0xe0, 0x07,
                };
                // 'icon_knob_over_oled', 16x16px
                
                // Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 384)
                const unsigned char* bitmap_icons[5] = {
                  bitmap_icon_sinkronisasi,
                  bitmap_icon_node_sensor_1,
                  bitmap_icon_node_sensor_2,
                  bitmap_icon_sleep,
                  bitmap_icon_set_waktu,
                };
                
                // Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 8320)
                // 'scrollbar_background', 8x64px
                const unsigned char bitmap_scrollbar_background [] PROGMEM = {
                  0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
                  0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
                  0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
                  0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
                  0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
                  0x00, 0x40, 0x00, 0x00,
                };
                
                // 'item_sel_outline', 128x21px
                const unsigned char bitmap_item_sel_outline [] PROGMEM = {
                  0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                  0xFF, 0xFF, 0xFF, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
                  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
                  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
                  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
                  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
                  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
                  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x0C, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xF8, 0xFF, 0xFF, 0xFF,
                  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
                };
                
                // ------------------ end generated bitmaps from image2cpp ---------------------------------
                
                const int NUM_ITEMS = 5; // number of items in the list and also the number of screenshots and screenshots with QR codes (other screens)
                const int MAX_ITEM_LENGTH = 20; // maximum characters for the item name
                
                char menu_items [NUM_ITEMS] [MAX_ITEM_LENGTH] = {  // array with item names
                  { "Sinkronisasi" },
                  { "Node Sensor 1" },
                  { "Node Sensor 2" },
                  { "Sleep" },
                  { "Set. Waktu" },
                };
                // note - when changing the order of items above, make sure the other arrays referencing bitmaps
                // also have the same order, for example array "bitmap_icons" for icons, and other arrays for screenshots and QR codes
                // TOMBOL MENU
                #define BUTTON_UP_PIN 27 // pin for UP button 
                #define BUTTON_SELECT_PIN 25 // pin for SELECT button
                #define BUTTON_DOWN_PIN 26 // pin for DOWN button
                int button_up_clicked = 0; // only perform action when button is clicked, and wait until another press
                int button_select_clicked = 0; // same as above
                int button_down_clicked = 0; // same as above
                int item_selected = 0; // which item in the menu is selected
                int item_sel_previous; // previous item - used in the menu screen to draw the item before the selected one
                int item_sel_next; // next item - used in the menu screen to draw next item after the selected one
                int current_screen = 0;   // 0 = menu, 1 = screenshot, 2 = qr
                
                //ATUR WAKTU
                int tombol_up = 0; // only perform action when button is clicked, and wait until another press
                int tombol_ok = 0; // same as above
                int tombol_down = 0; // same as above
                int item_terpilih = 0; // which item in the menu is selected
                int aksi_sekarang = 0;   // 0 = menu, 1 = screenshot, 2 = qr
                int tombol_ok_sinkron = 0;
                int kurang = 0;
                int dino;
                
                // RTC DS1307
                RTC_DS1307 rtc;
                //uint8_t set_tahun, set_bulan, set_tanggal, set_jam, set_menit, set_detik;
                uint8_t  bulan, tanggal, jam, menit, detik;
                uint16_t tahun;
                String hari, jam_up, menit_up, detik_up, sync_time;
                unsigned long delay_rtc;
                String timstep;
                char daysOfTheWeek[7][12] = {
                  "Sunday",
                  "Monday",
                  "Tuesday",
                  "Wednesday",
                  "Thursday",
                  "Friday",
                  "Saturday"
                };
                
                // SD Card
                unsigned long delaysd;
                unsigned long delaytampil;
                String simpan_waktu, simpan_node1, simpan_node2;
                String hrate1, suhu1, lon1, lat1, alt1, hrate2, suhu2, lon2, lat2, alt2;
                
                // LORA
                #define NODESENSOR1 2 //NODE SENSOR 1
                #define NODESENSOR2 4 //NODE SENSOR 1
                #define ENABLE_RSSI true
                String pesan_n1, pesan_n2, pesan;
                
                //int detik;
                //----------------------------------- File SD -----------------------------------------
                //SDCARD READ FILES
                void readFile(fs::FS &fs, const char * path) {
                  //Serial.printf("Reading file: %s\n", path);
                
                  File file = fs.open(path);
                  if (!file) {
                    //Serial.println("Failed to open file for reading");
                    return;
                  }
                
                  Serial.println("Read from file: ");
                  while (file.available()) {
                    Serial.write(file.read());
                  }
                  file.close();
                }
                //SDCARD WRITE FILES
                void writeFile(fs::FS &fs, const char * path, const char * message) {
                  File file = fs.open(path, FILE_WRITE);
                  if (!file) {
                    return;
                  }
                  if (file.print(message)) {
                  } else {
                  }
                  file.close();
                }
                //SDCARD APPEND
                void appendFile(fs::FS &fs, const char * path, const char * message) {
                  File file = fs.open(path, FILE_APPEND);
                  if (!file) {
                    return;
                  }
                  if (file.print(message)) {
                  } else {
                  }
                  file.close();
                }
                //SDCARD RENAME FILES
                void renameFile(fs::FS &fs, const char * path1, const char * path2) {
                  if (fs.rename(path1, path2)) {
                  } else {
                  }
                }
                //SDCARD DELETE FILES
                void deleteFile(fs::FS &fs, const char * path) {
                  if (fs.remove(path)) {
                  } else {
                  }
                }
                // ------------------------------------ Menu 1--------------------------------------------
                
                // -----------------------------------------------------------------------------------------------------------
                void sinkronisasi(void) {
                  //u8g2.setFont(u8g2_font_4x6_tf);
                  //u8g2.setFont(u8g2_font_u8glib_4_tf);
                  //u8g2.setFont(u8g2_font_6x10_mf);
                  //u8g2.drawStr(20, 32 + 11 + 15, timstep.c_str());
                
                  u8g2.setFont(u8g2_font_artosserif8_8r);
                  u8g2.drawStr(0, 20, "Pesan diterima :");
                  u8g2.drawStr(0, 30, pesan.c_str());
                  //u8g2.drawStr(0, 40, "Siap Untuk Sinkronisasi");
                }
                void node1(void) {
                  u8g2.setFont(u8g2_font_amstrad_cpc_extended_8f);/////////////Font Bagus
                  u8g2.drawStr(0, 20, "Long : 1234567");
                  //u8g2.setFont(u8g2_font_u8glib_4_tf);
                  u8g2.drawStr(0, 29, "Lati : 1234567");
                  //u8g2.setFont(u8g2_font_6x10_mf);
                  u8g2.drawStr(0, 38, "Alti : 123 mdpl");
                  //u8g2.setFont(u8g2_font_6x10_mf);
                  u8g2.drawStr(0, 47, "Wind : 123 km/j");
                }
                void node2(void) {
                  u8g2.setFont(u8g2_font_artosserif8_8r);
                  u8g2.drawStr(0, 20, "Long : 1234567");
                  //u8g2.setFont(u8g2_font_u8glib_4_tf);
                  u8g2.drawStr(0, 29, "Lati : 1234567");
                  //u8g2.setFont(u8g2_font_6x10_mf);
                  u8g2.drawStr(0, 38, "Alti : 123 mdpl");
                  //u8g2.setFont(u8g2_font_6x10_mf);
                  u8g2.drawStr(0, 47, "Wind : 123 km/j");
                }
                void turu(void) {
                  u8g2.setFont(u8g2_font_6x10_mf);
                  u8g2.drawStr(0, 20, "Tekan Lagi");
                  u8g2.drawStr(0, 30, "Untuk Mode ");
                  u8g2.drawStr(0, 40, "Tidur ");
                }
                void setwaktu(void) {
                  String dis_waktu = String(jam_up) + ":" + String(menit_up) + ":" + String(detik_up);
                  String dis_tanggal = String(tanggal) + "/" + String(bulan) + "/" + String(tahun);
                  //String dis_timstep = String(timstep);
                
                  u8g2.setFont(u8g2_font_logisoso20_tf);
                  u8g2.drawStr(15, 21, dis_waktu.c_str());
                  u8g2.setFont(u8g2_font_amstrad_cpc_extended_8f);
                  u8g2.drawStr(25, 32, hari.c_str());
                  u8g2.drawStr(25, 32 + 11, dis_tanggal.c_str());
                  u8g2.drawStr(20, 32 + 11 + 15, timstep.c_str());
                }
                void gelap(void) {
                  //u8g2.setFont(u8g2_font_artosserif8_8r);
                  //u8g2.drawStr(0, 18, "Long : 1234567");
                }
                
                //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| SET WAKTU |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
                
                void set_waktu() {
                  DateTime now = rtc.now();
                
                  if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (tombol_ok_sinkron == 0)) { // select button clicked, jump between screens
                    tombol_ok_sinkron = 1; // set button to clicked to only perform the action once
                    if (aksi_sekarang == 0) {
                      aksi_sekarang = 1;
                    }
                    else if (aksi_sekarang == 1) {
                      aksi_sekarang = 2;
                    }
                    else if (aksi_sekarang == 2) {
                      aksi_sekarang = 3;
                    }
                    else if (aksi_sekarang == 3) {
                      aksi_sekarang = 4;
                    }
                    else if (aksi_sekarang == 4) {
                      aksi_sekarang = 5;
                    }
                    else if (aksi_sekarang == 5) {
                      aksi_sekarang = 6;
                    }
                    else if (aksi_sekarang == 6) {
                      aksi_sekarang = 7;
                    }
                    else {
                      aksi_sekarang = 0;
                    }
                  }
                  if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (tombol_ok_sinkron == 1)) { // unclick
                    tombol_ok_sinkron = 0;
                  }
                  //u8g2.clearBuffer();  // clear buffer for storing display content in RAM
                  if (aksi_sekarang == 0) { // MENU SCREEN
                    tahun = now.year();
                    bulan = now.month();
                    tanggal = now.day();
                    jam = now.hour();
                    menit = now.minute();
                    detik = now.second();
                    timstep = now.timestamp();
                    hari = String(daysOfTheWeek[now.dayOfTheWeek()]);
                    jam_up = String(jam);
                    menit_up = String(menit);
                    detik_up = String(detik);
                    if (jam < 10) {
                      jam_up = "0" + String(jam);
                    }
                    if (menit < 10) {
                      menit_up = "0" + String(menit);
                    }
                    if (detik < 10) {
                      detik_up = "0" + String(detik);
                    }
                    setwaktu();
                  }
                  //GANTI TANGGAL
                  else if (aksi_sekarang == 1) {
                    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (tombol_up == 0)) { // up button clicked - jump to previous menu item
                      tombol_up = 1; // set button to clicked to only perform the action once
                      tanggal++;
                      if (tanggal > 31) {
                        tanggal = 1;
                      }
                    }
                    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (tombol_up == 1)) { // unclick
                      tombol_up = 0;
                    }
                    setwaktu();
                  }
                
                  //GANTI BULAN
                  else if (aksi_sekarang == 2) {
                    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (tombol_up == 0)) { // up button clicked - jump to previous menu item
                      tombol_up = 1; // set button to clicked to only perform the action once
                      bulan ++;
                      if (bulan > 12) {
                        bulan = 1;
                      }
                    }
                    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (tombol_up == 1)) { // unclick
                      tombol_up = 0;
                    }
                    setwaktu();
                  }
                
                  //GANTI TAHUN
                  else if (aksi_sekarang == 3) {
                    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (tombol_up == 0)) { // up button clicked - jump to previous menu item
                      tombol_up = 1; // set button to clicked to only perform the action once
                      tahun ++;
                      if (tahun > 2030) {
                        tahun = 2020;
                      }
                    }
                    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (tombol_up == 1)) { // unclick
                      tombol_up = 0;
                    }
                    setwaktu();
                  }
                
                  //GANTI JAM
                  else if (aksi_sekarang == 4) {
                    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (tombol_up == 0)) { // up button clicked - jump to previous menu item
                      tombol_up = 1; // set button to clicked to only perform the action once
                      jam ++;
                      if (jam > 23) {
                        jam = 1;
                      }
                      jam_up = String(jam);
                    }
                
                    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (tombol_up == 1)) { // unclick
                      tombol_up = 0;
                    }
                    setwaktu();
                  }
                  //GANTI MENIT
                  else if (aksi_sekarang == 5) {
                    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (tombol_up == 0)) { // up button clicked - jump to previous menu item
                      tombol_up = 1; // set button to clicked to only perform the action once
                      menit ++;
                      if (menit > 59) {
                        menit = 1;
                      }
                      menit_up = String(menit);
                    }
                
                    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (tombol_up == 1)) { // unclick
                      tombol_up = 0;
                    }
                    setwaktu();
                  }
                  //GANTI DETIK
                  else if (aksi_sekarang == 6) {
                    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (tombol_up == 0)) { // up button clicked - jump to previous menu item
                      tombol_up = 1; // set button to clicked to only perform the action once
                      detik ++;
                      if (detik > 59) {
                        detik = 1;
                      }
                      detik_up = String(detik);
                    }
                
                    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (tombol_up == 1)) { // unclick
                      tombol_up = 0;
                    }
                    setwaktu();
                  }
                
                  else if (aksi_sekarang == 7) {
                    //rtc.setTime();  // SS,MM,HH,Date,Month,Year
                    rtc.adjust(DateTime(tahun, bulan, tanggal, jam, menit, detik));
                    setwaktu();
                    aksi_sekarang = 0;
                  }
                  //setwaktu();
                }
                
                //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| END SET WAKTU ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
                void printParameters(struct Configuration configuration);
                void printModuleInformation(struct ModuleInformation moduleInformation);
                // -----------------------------------------------------------------------------------------------------------
                void setup() {
                  Serial.begin(9600);
                  //LORA
                  ResponseStructContainer c;
                  c = e220ttl.getConfiguration();
                  // It's important get configuration pointer before all other operation
                  Configuration configuration = *(Configuration*) c.data;
                  Serial.println(c.status.getResponseDescription());
                  Serial.println(c.status.code);
                  printParameters(configuration);
                  ////////////////////////////////////////////////////////////////////////////////////////
                  //----------------------- FIXED RECEIVER RSSI -----------------------
                  configuration.ADDL = 0x03;
                  configuration.ADDH = 0x00;
                  configuration.CHAN = 23;
                
                  configuration.SPED.uartBaudRate = UART_BPS_9600;
                  configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
                  configuration.SPED.uartParity = MODE_00_8N1;
                
                  configuration.OPTION.subPacketSetting = SPS_200_00;
                  configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_DISABLED;
                  configuration.OPTION.transmissionPower = POWER_22;
                
                  configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED;
                  configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
                  configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED;
                  configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;
                
                  ResponseStatus rs = e220ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_SAVE);
                  //Serial.println(rs.getResponseDescription());
                 // Serial.println(rs.code);
                  c.close();
                  ////////////////////////////////////////////////////////////////////////////////////////
                
                  u8g2.setColorIndex(1);  // set the color to white
                  u8g2.begin();
                  u8g2.setBitmapMode(1);
                
                  //RTC
                  rtc.begin();
                
                  // define pins for buttons
                  // INPUT_PULLUP means the button is HIGH when not pressed, and LOW when pressed
                  // since it´s connected between some pin and GND
                  pinMode(BUTTON_UP_PIN, INPUT_PULLUP); // up button
                  pinMode(BUTTON_SELECT_PIN, INPUT_PULLUP); // select button
                  pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP); // down button
                
                  // MicroSD Card
                  if (!SD.begin()) {
                    Serial.println("Card Mount Failed");
                    return;
                  }
                  //deleteFile(SD, "/datalog.txt");
                  File file = SD.open("/databasis.txt");
                  if (!file) {
                    Serial.println("File doesn't exist");
                    Serial.println("Creating file...");
                    writeFile(SD, "/databasis.txt", "Apasih gajelas banget \r\n");
                  }
                  else {
                    Serial.println("File already exists");
                  }
                  appendFile(SD, "/databasis.txt", "| Tanggal | Hrate | Suhu | Latitude | Longitude | Altitude|\r\n");
                  appendFile(SD, "/databasis.txt", "===========================================================\r\n");
                  readFile(SD, "/databasis.txt");
                  file.close();
                
                  delay_rtc = millis();
                  delaysd = millis();
                }
                
                void loop() {
                
                  // when pin 13 is LOW (DEMO_PIN), enable demo mode
                  // this could be done either by using a switch
                  // or simply by connecting the wire between pin 13 and GND
                  // (those pins are next to each other)
                  if (current_screen == 0) { // MENU SCREEN
                
                    // up and down buttons only work for the menu screen
                    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0)) { // up button clicked - jump to previous menu item
                      item_selected = item_selected - 1; // select previous item
                      button_up_clicked = 1; // set button to clicked to only perform the action once
                      if (item_selected < 0) { // if first item was selected, jump to last item
                        item_selected = NUM_ITEMS - 1;
                      }
                    }
                    else if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0)) { // down button clicked - jump to next menu item
                      item_selected = item_selected + 1; // select next item
                      button_down_clicked = 1; // set button to clicked to only perform the action once
                      if (item_selected >= NUM_ITEMS) { // last item was selected, jump to first menu item
                        item_selected = 0;
                      }
                    }
                
                    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) { // unclick
                      button_up_clicked = 0;
                    }
                    if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) { // unclick
                      button_down_clicked = 0;
                    }
                
                  }
                
                  if ((digitalRead(BUTTON_SELECT_PIN) == LOW) && (button_select_clicked == 0)) { // select button clicked, jump between screens
                    button_select_clicked = 1; // set button to clicked to only perform the action once
                    if (current_screen == 0) {
                      current_screen = 1; // menu items screen --> screenshots screen
                    }
                    else if (current_screen == 1) {
                      current_screen = 2; // screenshots screen --> qr codes screen
                    }
                    else {
                      current_screen = 0; // qr codes screen --> menu items screen
                    }
                  }
                  if ((digitalRead(BUTTON_SELECT_PIN) == HIGH) && (button_select_clicked == 1)) { // unclick
                    button_select_clicked = 0;
                  }
                
                  // set correct values for the previous and next items
                  item_sel_previous = item_selected - 1;
                  if (item_sel_previous < 0) {
                    item_sel_previous = NUM_ITEMS - 1; // previous item would be below first = make it the last
                  }
                  item_sel_next = item_selected + 1;
                  if (item_sel_next >= NUM_ITEMS) {
                    item_sel_next = 0; // next item would be after last = make it the first
                  }
                
                  u8g2.clearBuffer();  // clear buffer for storing display content in RAM
                
                  if (current_screen == 0) { // MENU SCREEN
                
                    // selected item background
                    u8g2.drawXBMP(0, 22, 128, 21, bitmap_item_sel_outline);
                
                    // draw previous item as icon + label
                    u8g2.setFont(u8g_font_7x14);
                    u8g2.drawStr(25, 15, menu_items[item_sel_previous]);
                    u8g2.drawXBMP( 4, 2, 16, 16, bitmap_icons[item_sel_previous]);
                
                    // draw selected item as icon + label in bold font
                    u8g2.setFont(u8g_font_7x14B);
                    u8g2.drawStr(25, 15 + 20 + 2, menu_items[item_selected]);
                    u8g2.drawXBMP( 4, 24, 16, 16, bitmap_icons[item_selected]);
                
                    // draw next item as icon + label
                    u8g2.setFont(u8g_font_7x14);
                    u8g2.drawStr(25, 15 + 20 + 20 + 2 + 2, menu_items[item_sel_next]);
                    u8g2.drawXBMP( 4, 46, 16, 16, bitmap_icons[item_sel_next]);
                
                    // draw scrollbar background
                    u8g2.drawXBMP(128 - 8, 0, 8, 64, bitmap_scrollbar_background);
                
                    // draw scrollbar handle
                    u8g2.drawBox(125, 64 / NUM_ITEMS * item_selected, 3, 64 / NUM_ITEMS);
                
                    // draw upir logo
                    //u8g2.drawXBMP(128-16-4, 64-4, 16, 4, upir_logo);
                
                  }
                  else if (current_screen == 1) { // SCREENSHOTS SCREEN
                    if (item_selected == 0) {
                      sinkronisasi();
                    }
                    else if (item_selected == 1) {
                      node1();
                    }
                    else if (item_selected == 2) {
                      node2();
                    }
                    else if (item_selected == 3) {
                      turu();
                    }
                    else if (item_selected == 4) {
                      set_waktu();
                    }
                  }
                  else if (current_screen == 2) { // QR SCREEN
                    if (item_selected != 3) {
                      current_screen = 0;
                    }
                    else {
                      //do nothing
                    }
                  }
                  // Baca Pesan
                  baca_pesan();
                
                  // Kirim pesan Serial Monitor
                  kirim_pesan();
                
                  //Simpan setiap 10 detik
                  if (millis() - delaysd > 10000) {
                    //appendFile(SD, "/databasis.txt", simpan.c_str());
                    simpan_data();
                    detik = detik + 10;
                    delaysd = millis();
                  }
                
                  u8g2.sendBuffer();
                }
                
                void kirim_pesan() {
                  if (Serial.available()) {
                    String input = Serial.readString();
                    ResponseStatus rs = e220ttl.sendFixedMessage(0, NODESENSOR1, 23, input);
                    // Check If there is some problem of succesfully send
                   // Serial.println(rs.getResponseDescription());
                  }
                }
                
                void baca_pesan() {
                 if (e220ttl.available() > 1) {
                    // read the String message
                #ifdef ENABLE_RSSI
                    ResponseContainer rc = e220ttl.receiveMessageRSSI();
                #else
                    ResponseContainer rc = e220ttl.receiveMessage();
                #endif
                    // Is something goes wrong print error
                    if (rc.status.code != 1) {
                      Serial.println(rc.status.getResponseDescription());
                    } else {
                      Print the data received
                      Serial.println(rc.status.getResponseDescription());
                      Serial.println(rc.data);
                #ifdef ENABLE_RSSI
                      Serial.print("RSSI: "); Serial.println(rc.rssi, DEC);
                #endif
                    }
                    pesan = String(rc.data);
                  }
                }
                
                void simpan_data() {
                  DateTime now = rtc.now();
                  simpan_waktu = String(daysOfTheWeek[now.dayOfTheWeek()]) + ", " + String(now.hour()) + ":" + String(now.minute()) + "|" + String(now.second()) + "\r\n";
                  simpan_node1 = String("Node 1") + "|" + hrate1 + "|" + suhu1 + "|" + lon1 + "|" + lat1 + "|" + alt1 + "\r\n";
                  simpan_node2 = String("Node 2") + "|" + hrate2 + "|" + suhu2 + "|" + lon2 + "|" + lat2 + "|" + alt2 + "\r\n";
                  appendFile(SD, "/databasis.txt", simpan_waktu.c_str());
                  appendFile(SD, "/databasis.txt", simpan_node1.c_str());
                  appendFile(SD, "/databasis.txt", simpan_node2.c_str());
                }
                
                void printParameters(struct Configuration configuration) {
                  Serial.println("----------------------------------------");
                
                  Serial.print(F("HEAD : "));  Serial.print(configuration.COMMAND, HEX);Serial.print(" ");Serial.print(configuration.STARTING_ADDRESS, HEX);Serial.print(" ");Serial.println(configuration.LENGHT, HEX);
                  Serial.println(F(" "));
                  Serial.print(F("AddH : "));  Serial.println(configuration.ADDH, HEX);
                  Serial.print(F("AddL : "));  Serial.println(configuration.ADDL, HEX);
                  Serial.println(F(" "));
                  Serial.print(F("Chan : "));  Serial.print(configuration.CHAN, DEC); Serial.print(" -> "); Serial.println(configuration.getChannelDescription());
                  Serial.println(F(" "));
                  Serial.print(F("SpeedParityBit     : "));  Serial.print(configuration.SPED.uartParity, BIN);Serial.print(" -> "); Serial.println(configuration.SPED.getUARTParityDescription());
                  Serial.print(F("SpeedUARTDatte     : "));  Serial.print(configuration.SPED.uartBaudRate, BIN);Serial.print(" -> "); Serial.println(configuration.SPED.getUARTBaudRateDescription());
                  Serial.print(F("SpeedAirDataRate   : "));  Serial.print(configuration.SPED.airDataRate, BIN);Serial.print(" -> "); Serial.println(configuration.SPED.getAirDataRateDescription());
                  Serial.println(F(" "));
                  Serial.print(F("OptionSubPacketSett: "));  Serial.print(configuration.OPTION.subPacketSetting, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getSubPacketSetting());
                  Serial.print(F("OptionTranPower    : "));  Serial.print(configuration.OPTION.transmissionPower, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getTransmissionPowerDescription());
                  Serial.print(F("OptionRSSIAmbientNo: "));  Serial.print(configuration.OPTION.RSSIAmbientNoise, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getRSSIAmbientNoiseEnable());
                  Serial.println(F(" "));
                  Serial.print(F("TransModeWORPeriod : "));  Serial.print(configuration.TRANSMISSION_MODE.WORPeriod, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getWORPeriodByParamsDescription());
                  Serial.print(F("TransModeEnableLBT : "));  Serial.print(configuration.TRANSMISSION_MODE.enableLBT, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getLBTEnableByteDescription());
                  Serial.print(F("TransModeEnableRSSI: "));  Serial.print(configuration.TRANSMISSION_MODE.enableRSSI, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getRSSIEnableByteDescription());
                  Serial.print(F("TransModeFixedTrans: "));  Serial.print(configuration.TRANSMISSION_MODE.fixedTransmission, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getFixedTransmissionDescription());
                  Serial.println("----------------------------------------");
                }
                void printModuleInformation(struct ModuleInformation moduleInformation) {
                  Serial.println("----------------------------------------");
                  Serial.print(F("HEAD: "));  Serial.print(moduleInformation.COMMAND, HEX);Serial.print(" ");Serial.print(moduleInformation.STARTING_ADDRESS, HEX);Serial.print(" ");Serial.println(moduleInformation.LENGHT, DEC);
                  Serial.print(F("Model no.: "));  Serial.println(moduleInformation.model, HEX);
                  Serial.print(F("Version  : "));  Serial.println(moduleInformation.version, HEX);
                  Serial.print(F("Features : "));  Serial.println(moduleInformation.features, HEX);
                  Serial.println("----------------------------------------");
                }

                I’m sorry if my code appears messy.

                #28101
                Eryk
                Participant

                  Hello Renzo, love your post about PCF8574.
                  I’m doing now a engineer project for my degree and i have a problem. Im using a freenove esp32-wrover-cam(i can post a link to a pinout of this esp32).
                  Pinout:
                  https://makeradvisor.com/wp-content/uploads/2023/02/Freenove-ESP32-Wrover-CAM-pinout.jpg

                  I’m using a cam and wifi on this board, and also i need 7 pins to run other elements (3 buttons, 2 i2c(SDA SLC) for a 64×128 oled display, 1 pin to control POWER LED converter and 1 pin to control transistor controling a small motor). Because of my need of usage a cam and wifi i only left with two ports, 32 and 33, because CAM is disabling all cam ports and wifi is disabling all ACD2 ports. And one of sollutions i found is i2c expander like PCF8574, I managed to emulate i2c on 32 and 33 ports to turn on an display so i thought it would work with expander that way. I bought PCF8574 and i connected it with esp32
                  esp32 -> pcf8574
                  vcc -> vcc
                  GND->GND
                  32 -> SCL
                  33-> SDA
                  I tried to programm a simple code to test a button state read, but it doesn’t work

                  #include <Wire.h>
                  #include “PCF8574.h”

                  // Instantiate Wire for generic use at 400kHz
                  TwoWire I2Cone = TwoWire(0);
                  // Instantiate Wire for generic use at 100kHz
                  TwoWire I2Ctwo = TwoWire(1);

                  // Set i2c address
                  PCF8574 pcf8574(&I2Ctwo, 0x20);
                  //PCF8574 pcf8574(&I2Ctwo, 0x20, 32, 33);
                  // PCF8574(TwoWire *pWire, uint8_t address, uint8_t interruptPin, void (*interruptFunction)() );
                  // PCF8574(TwoWire *pWire, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interruptPin, void (*interruptFunction)());

                  //#define I2C_SDA 33
                  //#define I2C_SCL 32
                  //Wire.begin(I2C_SDA, I2C_SCL);

                  void setup() {
                  Serial.begin(115200);
                  // put your setup code here, to run once:
                  I2Cone.begin(33,32,400000); // SDA pin 33, SCL pin 32, 400kHz frequency

                  pcf8574.pinMode(P2, INPUT_PULLUP);
                  pcf8574.begin();
                  }

                  void loop() {
                  // put your main code here, to run repeatedly:
                  int buttonState = pcf8574.digitalRead(P2);
                  Serial.println(buttonState);
                  }

                  I connecter the bottom with P2 port and it doesn’t work. I don’t know if my esp32 is connecting to this expander or not.

                  Also another important question, can I emulate a SDA and SCL ports for my display on PCF8574 ports(P0-P7), or i can use other SDA SCL ports on other side of the PCF8574 board? If not then only solluction i have is to use 2 esp32 for this project.

                  Renzo Mischianti
                  Keymaster

                    Ciao Dario,
                    gli esp uno vale l’altro (a meno di dover gestire il risparmio energetico), è bene prendere quello che ci soddisfa di più.

                    Per i pin basta che controlli sulla scheda sono tutti numerati ad eccezione del joistick che sembri usare questi pin FLATH, RSET, D5, D6, e D7, ma non è chiaro a cosa corrisponde FLATH.
                    E del display oled che usa SDA e SCL connessi a D1 e D2 rispettivamente.

                    I pin che trovi sulla scheda a parità di nome hanno le stesse funzioni di un qualsiasi esp8266.

                    Ciao Renzo

                    Attachments:
                    You must be logged in to view attached files.
                    Peo.Marameo
                    Participant

                      Buongiorno a tutti,
                      mi chiamo Dario e sono alla base mecchanico industriale con la passione di capire e di fare.
                      Uso saltuariamente Arduino e non posso definirmi programmatore, guardo, capisco e trasferisco le idee che ho, e applico cio che trovo come info in qualche cosa che funzioni.
                      Ho usato questo modulo di Wemos ” ESP8266 WiFi NodeMCU Modulo 18650 Batteria 0.96in Display OLED ” per fare un piccolo telecomando per le telecamerine tipo GoPro, trovate il video sul tubo cercando il mio user ID, non mi servivano uscite, adesso ho pensato ad aggiungere qualche cosa, ma non trovo la piedinatura per poter utilizzare i pin a disposizione, qualcuno tra voi ha a disposizione la corrispondenza numerica dei pin, o ancora meglio lo schema??
                      Potrei usare altre schede, ma il vantaggi è che ha un piccolo monitor, un pulsante gia cablato e soprattutto la sua bella batteria.
                      Scusate se sono stato prolisso ma, pensavo fosse giusto presentarmi, in fondo entro a casa vostra.
                      Buona giornata
                      Il Peo Marameo

                      #22165
                      Renzo Mischianti
                      Keymaster

                        Hi John,
                        you can find a version with RTC here.

                        You must add an i2c RTC by sharing the pin of OLED display.
                        But It’s all undocumented.

                        I Attach the preview.
                        Bye Renzo

                        Attachments:
                        You must be logged in to view attached files.
                      Viewing 15 results - 1 through 15 (of 23 total)