Skocz do zawartości

esp32 błąd biblioteki


Pomocna odpowiedź

1 minutę temu, trainee napisał:

Możesz też powiedzieć jaką wartość ma KONTAKTRON. I czy przypadkiem nie jest taka sama jak ta LET_BUILTIN.

Nie wiem jaką ma wartość.

#define KONTAKTRON 18
 
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
 /*
  pinMode(KONTAKTRON, INPUT_PULLUP); //Kontaktron jako wejście
  
  digitalWrite(LED_BUILTIN, LOW); //Dioda wyłączona
  */
}
 
void loop() {
  if (digitalRead(KONTAKTRON) == LOW) { //Jeśli czujnik zwarty
 //Stan OK - dioda swieci caly czas
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
  } else {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);//Stan ALARM - dioda  mruga
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
 }
}

Dioda świeci cały czas.

#define KONTAKTRON 18
 
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
 
  pinMode(KONTAKTRON, INPUT_PULLUP); //Kontaktron jako wejście
  
  //digitalWrite(LED_BUILTIN, LOW); //Dioda wyłączona
  
}
 
void loop() {
  if (digitalRead(KONTAKTRON) == LOW) { //Jeśli czujnik zwarty
 //Stan OK - dioda swieci caly czas
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
  } else {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);//Stan ALARM - dioda  mruga
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
 }
}

Dioda miga i Kontaktron działa

Kod działa

#define KONTAKTRON 18
 
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
 
  pinMode(KONTAKTRON, INPUT_PULLUP); //Kontaktron jako wejście
  
  digitalWrite(LED_BUILTIN, LOW); //Dioda wyłączona
  delay(1000);
}
 
void loop() {
  if (digitalRead(KONTAKTRON) == LOW) { //Jeśli czujnik zwarty
 //Stan OK - dioda swieci caly czas
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
  } else {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);//Stan ALARM - dioda  mruga
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
 }
}

Ale i tak trzeba to przerobić na mils. Oraz zmienić aby po ponownym zwarciu kontaktrona dioda cały czas migała

(edytowany)

Ok, w takim razie trochę podpowiem.

Na początek miganie diodą - w przypadku cywilizowanej biblioteki digitalWrite() pewnie sterowałoby GPIO. Niestety mamy do czynienia z Arduino, więc pod spodem znajdziemy taki kod:

extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val)
{
    #ifdef RGB_BUILTIN
        if(pin == RGB_BUILTIN){
            //use RMT to set all channels on/off
            const uint8_t comm_val = val != 0 ? RGB_BRIGHTNESS : 0;
            neopixelWrite(RGB_BUILTIN, comm_val, comm_val, comm_val);
            return;
        }
    #endif
	gpio_set_level((gpio_num_t)pin, val);
}

(żródło: https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c)

Nie mam słów dość obraźliwych, żeby wyrazić jak bardzo złe jest to rozwiązanie, chociaż w sumie to nie zaskakuje.

Mamy więc w digitalWrite paskudny warunek, jeśli pin == RGB_BUILTIN to zamiast gpio_set_level() wywołaj neopixelWrite().

Jak łatwo się domyślić na tej płytce ewaluacyjnej RGB_BUILTIN ma tę samą wartość co LED_BUILTIN. Dlatego program działa, chociaż nie powinien - jak słusznie zauważył kolega @trainee

Niestety funkcja neopixelWrite() to nie proste sterowanie pinu, jeśli wierzyć komentarzom używa RMT i jak widać jej wywołanie zajmuje trochę czasu. Do tego jest tak kiepsko napisana, że ponowne jej wywołanie w zbyt krótkim odstępie czasu psuje komunikację z diodą RGB.

 

Edytowano przez Elvis
  • Lubię! 1
28 minut temu, Elvis napisał:
    #ifdef RGB_BUILTIN
        if(pin == RGB_BUILTIN){
            //use RMT to set all channels on/off
            const uint8_t comm_val = val != 0 ? RGB_BRIGHTNESS : 0;
            neopixelWrite(RGB_BUILTIN, comm_val, comm_val, comm_val);
            return;
        }
    #endif

😱😱😱

No nie wierzę własnym oczom. Nie przyszło mi do głowy tam szukać, miałem taką myśl, że może protokół tej diody jest tak zrobiony, że jak będzie się trzymać jeden stan to "jakoś działa". Okropne!

Chociaż nie rzucałbym od razu kamieniami w Arduino per se, a w Espressif, do którego to repo należy. W bazowym Arduino AVR nie znajduję na szybko takich cudów.

@Elvis, może byś im tam zgłosił to Twoje znalezisko, że to jest po prostu czyste zło? A zamiast tego mogą po prostu nie definiować LED_BUILTIN, zamiast wariactwa, żeby przykłady się łatwiej odpalały. Opisowa dokumentacja sugeruje, że nie zawsze jest obecny:
 

Cytat

Defining built-ins: LED_BUILTIN

Most Arduino boards have a pin connected to an on-board LED in series with a resistor. The constant LED_BUILTIN is the number of the pin to which the on-board LED is connected. Most boards have this LED connected to digital pin 13.

(https://www.arduino.cc/reference/en/language/variables/constants/constants/)

A na dowód, z dysku:

~/.arduino15/packages/arduino/hardware/avr/1.8.6/variants$ grep -L LED_BUILTIN */pins_arduino.h
eightanaloginputs/pins_arduino.h
micro/pins_arduino.h
robot_control/pins_arduino.h
robot_motor/pins_arduino.h
yun/pins_arduino.h

@trainee Wydaje mi się, że to klasyczny przypadek "it's not bug, it's a feature". Autorzy biblioteki chcieli mieć zgodność z przykładami dla innych płytek, więc mają.

Zawsze można się zastanowić, czy to faktycznie zły kod, czy po prostu ja się czepiam. Bo w sumie są użytkownicy biblioteki Arduino, korzystają z niej i są zadowoleni.

Ja zamiast zgłaszać co sądzę o tym kodzie wolę go po prostu nie używać. ESP32 ma bardzo przyzwoite SDK, moim zdaniem warto z niego korzystać zamiast nakładki, która niekoniecznie jest idealna.

(edytowany)
1 godzinę temu, Elvis napisał:

Zawsze można się zastanowić, czy to faktycznie zły kod

Tak, jest to ewidentnie zły kod.

Framework Arduino został pomyślany jako implementacja Wiringa, a tam digitalWrite jest określony jako zmiana stanu pinu, a nie zapalanie ledy. Czyli błąd.

Doskonale rozumiem podejście autorów, ale moim zdaniem uprościli sprawę. Wystarczyłoby w boards.txt dać dodatkowy przełącznik w menu do tej płytki (coś w stylu "RGB LED compat mode"), w platform.txt uwzględnić wystąpienie przełącznika, a w kodzie dać #ifdef. Wtedy po pierwsze nikt by się nie mógł przyczepić do kodu, a każdy mógłby przełączyć sobie działanie.

Nie mam tej płytki i nie planuję, toteż nie czuję się upoważniony do zgłaszania czegokolwiek autorom, ale gdybym miał to bym zgłosił.

1 godzinę temu, Elvis napisał:

ESP32 ma bardzo przyzwoite SDK, moim zdaniem warto z niego korzystać zamiast nakładki,

Na pewno. Zapominasz jednak o pewnej grupie użytkowników pisanego przez mnie czy Ciebie programu. Jak kiedyś wspomniałem, osoba niewidoma siadając po raz pierwszy do Arduino IDE jest w stanie bez problemu wgrać na płytkę dany program, nawet jeśli wymagałoby to kilku dodatkowych niestandardowych czynności (konkretniej chodziło o moja metrówkę). Jesteś w stanie napisać krótką instrukcję (niezależną od systemu operacyjnego użytkownika), jak to zrobić w przypadku tego ichniejszego SDK? Bo ja się tego raczej nie podejmę.

1 godzinę temu, Elvis napisał:

zamiast nakładki, która niekoniecznie jest idealna

To może lepiej zadbać o to, aby owa nakładka była jak najbliższa ideału? Z tego co się zorientowałem owej nakładki nie używasz, natomiast kolejny raz masz coś do powiedzenia na temat jej jakości... a ja uważam, że owa nakładka jest bardzo dobrze zrobiona (używając jej z powodzeniem w kilku projektach) i jedna wpadka nie przekreśla całości.

<span class="złośliwy">STM-owy Cube czy inny HAL jak rozumiem jest bezbłędny...</span>

 

 

Edytowano przez ethanak
  • Lubię! 1

Wczoraj wieczorem byłem już mocno zmęczony szukaniem błędu w kodzie przy którym aktualnie pracuję, problem z tego wątku potraktowałem po prostu jako przerywnik, oczyszczenie umysłu nad czymś łatwiejszym. Może dlatego byłem trochę zbyt krytyczny dla bibliotek Arduino.

W każdym razie płytki esp32 C3 DevkitC 02 nie posiadam, całe wyszukiwanie błędu było tylko na podstawie kodu i opisów działania kolegi @Michal88 Jeśli ktoś ma czas i chęć zgłaszać uwagi / błędy to zachęcam, ja się tym niestety nie zajmę.

Jak chodzi o biblioteki, to nie bronię STM32CubeHAL, ani nie twierdzę że jest to dobrze napisana biblioteka. Prawdę mówiąc zawodowo nie używam ani bibliotek Arduino, ani CubeHAL. I w sumie nie używam też mikrokontrolerów, chociaż czasem coś o nich piszę. Ale nie wiem co w tym złego.

A ja jestem ciekaw co byście powiedzieli na takie rozwiązanie...

W boards.txt w sekcji menu:

menu.RGBCompat=RGB LED compat mode

i w sekcji esp32c3:

esp32c3.menu.RGBCompat.on=On
esp32c3.menu.RGBCompat.on.build.defines=-DRGB_BUILTIN_COMPAT
esp32c3.menu.RGBCompat.off=Off
esp32c3.menu.RGBCompat.off.build.defines=

A w funkcji digitalWrite zamiana:

#ifdef RGB_BUILTIN

na

#if defined(RGB_BUILTIN) && defined(RGB_BUILTIN_COMPAT)

Ciekawe czy by zadziałało... nie mam jak sprawdzić 😞

 

1 godzinę temu, Elvis napisał:

zawodowo nie używam ani bibliotek Arduino

Zawodowo to ja też nie, ale hobbystyczne używanie też się liczy 🙂

 

A, jeszcze dodatkowo w funkcji digitalWrite zaraz po neoPixelWrite:

if (!xPortInIsrContext()) delay(cośtam);

To już absolutny ukłon w stronę Blink.ino (ciekawe ile ma wynosić ten "cośtam") 🙂

 

  • Lubię! 1

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...