Пины и EEPROM
- Войдите на сайт для отправки комментариев
Всем доброго дня!
Работаю над одним проектом, суть которого заключается в том, что надо управлять 8 отдельными лентами с адресными светодиодами WS2812B.
Для этого использую 8 различных пинов Ардуино (со второго по одиннадцатый) и библиотеку NeoPixel.
Все хорошо работало и ничего не предвещало головняка, пока не потребовалось доработка.
Добавилась запись определенных переменных в энергонезависимую память.
С записью/чтением все хорошо.
НО
отвалилось управление лентой на 11 пине.
Пробовал много различных вариантов и проверок (это далеко не первый мой проект), но с таким встречаюсь впервые. Добавляею функцию с запись в память - нет управления ленты, убираешь функцию с памятью - все ок.
Отсюда вопрос: влияет ли работа библиотеки EEPROM на какие либо пины?
Ну или может кто подскажет, в какую сторону копать, так как перепаять на другой пин уже довольно проблематично. Да и вообще хочу понять, в чем дело.
Поправка: с четвертого по 11 пин.
Ардуино нано использую.
Не влияет. Копать в сторону внимательного чтения кода.
возможно не хватает памяти. Восемь адрессных лент (какой длины?) на Нано - это может быть много.
Код перечитал, увы. Видимо, что то упускаю
По 200 диодов на каждой.
В память записываются 8 чисел (значения от о до 4 каждое) в восемь ячеек, соответственно.
Возьмите ардуину побольше.
Если цветовая картинка на каждой ленте своя, то это выходит 200 * 8 * 3 = 4800 байт, что абсолютно нереально для Нано
Если картинка одинаковая на все 8 лент - то как вы копируете сигнал с одного пина на 7 других?
Теперь самому стало интересно, как оно работало)
Каждая лента целиком горит одним из 5 цветов.
Цвета в ленте меняются с помощью цикла, в котором применяется цвет для n-го диода каждой из 8ми лент и отправляется команда зажечь его.
То есть лента загораются не одновременно, а по одному диоду, но быстро.
Возможно, оно работало поэтому.
Судя по развитию событий - без черной магии тут не обошлось.
Там все запаковано уже, с защитой от темных сил)
Ардуино побольше взять = перепаять все, чего хотелось бы избежать.
Но если не найду причин до понедельника, то, видимо, придется взять что то с большей памятью и пробовать.
Судя по развитию событий - без черной магии тут не обошлось.
нее, ту жеж сразу видно - шаман, а это Практическая магия )))
Мля, мы скетч когда-нибудь увидим?
А заодно проверку памяти в нём?
Или так и будем языком по ягодицам шлёпать?
Судя по развитию событий - без черной магии тут не обошлось.
Да, какая нахрен магия - стек пропорол кучу и началось веселье. "Вот тут вроде работает, а запятую поменял - всё свалилось нахрен". Впервой, что ли?
Судя по развитию событий - без черной магии тут не обошлось.
Да, какая нахрен магия - стек пропорол кучу и началось веселье. "Вот тут вроде работает, а запятую поменял - всё свалилось нахрен". Впервой, что ли?
Очень на это похоже.
Скажем так, не часто с таким сталкивался, а на Ардуино первый раз. И в голову не пришло в ту сторону копать)
За идею спасибо.
Но тут у меня опыта маловато.
Есть какие-либо варианты вылечить?
На ум пока приходит только какой-либо костыль типа очищения памяти после отправки в ленту (скорее всего чушь спорол, но хз)
Мля, мы скетч когда-нибудь увидим?
А заодно проверку памяти в нём?
Или так и будем языком по ягодицам шлёпать?
Как до ноута доберусь, скину.
Думаю, ближе к вечеру.
Мля, мы скетч когда-нибудь увидим? А заодно проверку памяти в нём? Или так и будем языком по ягодицам шлёпать?
Видел, говорю ж, чуть ближе к вечеру.
ну, таком разе "думаю, ближе к вечеру" и поговорим. А сейчас говорить не о чем.
Только ты уж сразу там и на память посмотри MemoryExplorer'ом. Библиотеку можно взять здесь.
Если гражданин уверяет, что на его nano точно работала конфигурация, которая требует 5кб рамы, то никакого стека тут нет - исключительно черная магия.
MemoryExplorer сказал следующее:
template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; } #include "MemoryExplorer.h" #include "Adafruit_NeoPixel.h" #include <EEPROM.h> #include <SoftwareSerial.h> #include <DFPlayer_Mini_Mp3.h> #define LED_COUNT 200 // Указываем, какое количество пикселей #define LED_PIN_1 11 // Указываем, к какому порту подключен вход ленты DIN. #define LED_PIN_2 10 #define LED_PIN_3 9 #define LED_PIN_4 8 #define LED_PIN_5 7 #define LED_PIN_6 6 #define LED_PIN_7 5 #define LED_PIN_8 4 int game_butPin[8] = {12,13,A0,A1,A2,A3,A4,A5}; int color_state [8] = {0,0,0,0,0,0,0,0}; int win_state[8]; bool color_button_state[8] = {true, true, true, true, true, true, true, true}; int win_but_num = 0; int memory_but_num = 0; int button_number; int state = 0; bool win_stat=false; int playerPin = 2; // плеер int brightness = 10;// яркость int relPin = 3; // индикация (реле) int volume = 10; // громкость int winBut = A6; // кнопка, показывает нужные цвета и ресет int memoryBut = A7; // кнопка програмирования цветов uint32_t red; uint32_t yellow; uint32_t blue; uint32_t green; uint32_t purple; uint32_t off; uint32_t ms_color = 0; uint32_t ms_memory = 0; uint32_t ms_win = 0; bool memory_button_state = true; bool win_button_state = true; Adafruit_NeoPixel LED_1 = Adafruit_NeoPixel(LED_COUNT, LED_PIN_1, NEO_GRB + NEO_KHZ800 ); Adafruit_NeoPixel LED_2 = Adafruit_NeoPixel(LED_COUNT, LED_PIN_2, NEO_GRB + NEO_KHZ800 ); Adafruit_NeoPixel LED_3 = Adafruit_NeoPixel(LED_COUNT, LED_PIN_3, NEO_GRB + NEO_KHZ800 ); Adafruit_NeoPixel LED_4 = Adafruit_NeoPixel(LED_COUNT, LED_PIN_4, NEO_GRB + NEO_KHZ800 ); Adafruit_NeoPixel LED_5 = Adafruit_NeoPixel(LED_COUNT, LED_PIN_5, NEO_GRB + NEO_KHZ800 ); Adafruit_NeoPixel LED_6 = Adafruit_NeoPixel(LED_COUNT, LED_PIN_6, NEO_GRB + NEO_KHZ800 ); Adafruit_NeoPixel LED_7 = Adafruit_NeoPixel(LED_COUNT, LED_PIN_7, NEO_GRB + NEO_KHZ800 ); Adafruit_NeoPixel LED_8 = Adafruit_NeoPixel(LED_COUNT, LED_PIN_8, NEO_GRB + NEO_KHZ800 ); SoftwareSerial mySerial(99, playerPin); // RX, TX void setup() { Serial.begin(9600); mySerial.begin(9600); delay(10); mp3_set_serial(mySerial); mp3_set_volume(volume); delay(10); LED_1.begin(); LED_2.begin(); LED_3.begin(); LED_4.begin(); LED_5.begin(); LED_6.begin(); LED_7.begin(); LED_8.begin(); delay(100); for (int i=0; i<8; i++){ pinMode(game_butPin[i],INPUT); } pinMode(winBut,INPUT); pinMode(memoryBut,INPUT); pinMode(relPin,OUTPUT); digitalWrite(relPin,0); red = LED_1.Color(255, 0, 0); // красный yellow = LED_1.Color(255, 255, 0); //желтый blue = LED_1.Color(0,0,255); //синий green = LED_1.Color(0, 255, 0); //зеленый purple = LED_1.Color(145, 0, 255); //фиолетовый off = LED_1.Color(0, 0, 0); // погасить светдиоды LED_1.setBrightness(brightness); LED_2.setBrightness(brightness); LED_3.setBrightness(brightness); LED_4.setBrightness(brightness); LED_5.setBrightness(brightness); LED_6.setBrightness(brightness); LED_7.setBrightness(brightness); LED_8.setBrightness(brightness); delay(50); get_memory(); first_state(); Serial.print("win_state "); for(int i=0;i<8;i++){ Serial.print(win_state[i]); Serial.print(" "); } Serial.println(); Serial.println("Start"); memoryReport("Fragmentation"); } void loop() { if(state==0){ color_but(); memory_button(); win_button(); game(); if(color_state[0]==win_state[0] && color_state[1]==win_state[1] && color_state[2]==win_state[2] && color_state[3]==win_state[3] && color_state[4]==win_state[4] && color_state[5]==win_state[5] && color_state[6]==win_state[6] && color_state[7]==win_state[7]){ win(); win_stat=true; } } if(state==1){ win_but_num=1; win_button(); if(win_stat==false){ win_button_color(); win_stat=true; } } if(state==2){ memory_button(); color_but(); game(); } } int win(){ state=1; Serial.println("WIN"); digitalWrite(relPin,1); } int win_button_color(){ byte i; for(i=0;i<8;i++){ if(win_state[i]==0){ if(i==0){ for(int k=0; k<LED_COUNT; k++){LED_1.setPixelColor(k, red);} LED_1.show(); } if(i==1){ for(int k=0; k<LED_COUNT; k++){LED_2.setPixelColor(k, red);} LED_2.show(); } if(i==2){ for(int k=0; k<LED_COUNT; k++){LED_3.setPixelColor(k, red);} LED_3.show(); } if(i==3){ for(int k=0; k<LED_COUNT; k++){LED_4.setPixelColor(k, red);} LED_4.show(); } if(i==4){ for(int k=0; k<LED_COUNT; k++){LED_5.setPixelColor(k, red);} LED_5.show(); } if(i==5){ for(int k=0; k<LED_COUNT; k++){LED_6.setPixelColor(k, red);} LED_6.show(); } if(i==6){ for(int k=0; k<LED_COUNT; k++){LED_7.setPixelColor(k, red);} LED_7.show(); } if(i==7){ for(int k=0; k<LED_COUNT; k++){LED_8.setPixelColor(k, red);} LED_8.show(); } } // if(win_state[i]==1){ if(i==0){ for(int k=0; k<LED_COUNT; k++){LED_1.setPixelColor(k, yellow);} LED_1.show(); } if(i==1){ for(int k=0; k<LED_COUNT; k++){LED_2.setPixelColor(k, yellow);} LED_2.show(); } if(i==2){ for(int k=0; k<LED_COUNT; k++){LED_3.setPixelColor(k, yellow);} LED_3.show(); } if(i==3){ for(int k=0; k<LED_COUNT; k++){LED_4.setPixelColor(k, yellow);} LED_4.show(); } if(i==4){ for(int k=0; k<LED_COUNT; k++){LED_5.setPixelColor(k, yellow);} LED_5.show(); } if(i==5){ for(int k=0; k<LED_COUNT; k++){LED_6.setPixelColor(k, yellow);} LED_6.show(); } if(i==6){ for(int k=0; k<LED_COUNT; k++){LED_7.setPixelColor(k, yellow);} LED_7.show(); } if(i==7){ for(int k=0; k<LED_COUNT; k++){LED_8.setPixelColor(k, yellow);} LED_8.show(); } } // if(win_state[i]==2){ if(i==0){ for(int k=0; k<LED_COUNT; k++){LED_1.setPixelColor(k, blue);} LED_1.show(); } if(i==1){ for(int k=0; k<LED_COUNT; k++){LED_2.setPixelColor(k, blue);} LED_2.show(); } if(i==2){ for(int k=0; k<LED_COUNT; k++){LED_3.setPixelColor(k, blue);} LED_3.show(); } if(i==3){ for(int k=0; k<LED_COUNT; k++){LED_4.setPixelColor(k, blue);} LED_4.show(); } if(i==4){ for(int k=0; k<LED_COUNT; k++){LED_5.setPixelColor(k, blue);} LED_5.show(); } if(i==5){ for(int k=0; k<LED_COUNT; k++){LED_6.setPixelColor(k, blue);} LED_6.show(); } if(i==6){ for(int k=0; k<LED_COUNT; k++){LED_7.setPixelColor(k, blue);} LED_7.show(); } if(i==7){ for(int k=0; k<LED_COUNT; k++){LED_8.setPixelColor(k, blue);} LED_8.show(); } } // if(win_state[i]==3){ if(i==0){ for(int k=0; k<LED_COUNT; k++){LED_1.setPixelColor(k, green);} LED_1.show(); } if(i==1){ for(int k=0; k<LED_COUNT; k++){LED_2.setPixelColor(k, green);} LED_2.show(); } if(i==2){ for(int k=0; k<LED_COUNT; k++){LED_3.setPixelColor(k, green);} LED_3.show(); } if(i==3){ for(int k=0; k<LED_COUNT; k++){LED_4.setPixelColor(k, green);} LED_4.show(); } if(i==4){ for(int k=0; k<LED_COUNT; k++){LED_5.setPixelColor(k, green);} LED_5.show(); } if(i==5){ for(int k=0; k<LED_COUNT; k++){LED_6.setPixelColor(k, green);} LED_6.show(); } if(i==6){ for(int k=0; k<LED_COUNT; k++){LED_7.setPixelColor(k, green);} LED_7.show(); } if(i==7){ for(int k=0; k<LED_COUNT; k++){LED_8.setPixelColor(k, green);} LED_8.show(); } } // if(win_state[i]==4){ if(i==0){ for(int k=0; k<LED_COUNT; k++){LED_1.setPixelColor(k, purple);} LED_1.show(); } if(i==1){ for(int k=0; k<LED_COUNT; k++){LED_2.setPixelColor(k, purple);} LED_2.show(); } if(i==2){ for(int k=0; k<LED_COUNT; k++){LED_3.setPixelColor(k, purple);} LED_3.show(); } if(i==3){ for(int k=0; k<LED_COUNT; k++){LED_4.setPixelColor(k, purple);} LED_4.show(); } if(i==4){ for(int k=0; k<LED_COUNT; k++){LED_5.setPixelColor(k, purple);} LED_5.show(); } if(i==5){ for(int k=0; k<LED_COUNT; k++){LED_6.setPixelColor(k, purple);} LED_6.show(); } if(i==6){ for(int k=0; k<LED_COUNT; k++){LED_7.setPixelColor(k, purple);} LED_7.show(); } if(i==7){ for(int k=0; k<LED_COUNT; k++){LED_8.setPixelColor(k, purple);} LED_8.show(); } } } } int color_but(){ uint32_t ms1 = millis(); for(int i=0; i<8; i++){ // Фиксируем нажатие кнопки if( digitalRead(game_butPin [i]) == LOW && !color_button_state[i] && ( ms1 - ms_color ) > 50 ){ button_number = i; color_state [i] = color_state [i] + 1; if (color_state [i] >= 5) {color_state [i] = 0;} Serial.print("Button "); Serial.print(button_number); Serial.print(" pressed, state = "); Serial.print(color_state [i]); Serial.println(); color_button_state[i] = true; ms_color = ms1; } // Фиксируем отпускание кнопки if( digitalRead(game_butPin [i]) == HIGH && color_button_state[i] && ( ms1 - ms_color ) > 50 ){ color_button_state[i] = false; ms_color = ms1; } } } int memory_button(){ uint32_t ms2 = millis(); // Фиксируем нажатие кнопки if( analogRead(memoryBut) < 300 && !memory_button_state && ( ms2 - ms_memory) > 50 ){ memory_button_state = true; ms_memory = ms2; Serial.print("MEMORY BUTTON PRESSED"); Serial.println(); memory_but_num = memory_but_num+1; delay(100); if(memory_but_num==1){ while(analogRead(memoryBut) < 300){delay(10);} Serial.print("Redy to record"); mp3_play(1); first_state(); delay(1000); off_state(); delay(1000); first_state(); state=2;} if(memory_but_num==2){ Serial.println("record..."); mp3_play(2); delay(100); take_memory();} } // Фиксируем отпускание кнопки if( analogRead(memoryBut) > 700 && memory_button_state && ( ms2 - ms_memory) > 50 ){ memory_button_state = false; ms_memory = ms2; } } int win_button(){ uint32_t ms3 = millis(); // Фиксируем нажатие кнопки if( analogRead(winBut) < 300 && !win_button_state && ( ms3 - ms_win) > 50 ){ win_button_state = true; ms_win = ms3; Serial.print("WIN BUTTON PRESSED"); Serial.println(); win_but_num = win_but_num+1; delay(100); if(win_but_num==1){ while(analogRead(winBut) < 300){delay(10);} Serial.println("Button win");win();} if(win_but_num==2){ Serial.println("Reset"); delay(100);softReset();} } // Фиксируем отпускание кнопки if( analogRead(winBut) > 700 && win_button_state && ( ms3 - ms_win) > 50 ){ win_button_state = false; ms_win = ms3; } } int game(){ byte i; for(i=0;i<8;i++){ if(color_state[i]==0){ if(i==0){ for(int k=0; k<LED_COUNT; k++){LED_1.setPixelColor(k, red);} LED_1.show(); } if(i==1){ for(int k=0; k<LED_COUNT; k++){LED_2.setPixelColor(k, red);} LED_2.show(); } if(i==2){ for(int k=0; k<LED_COUNT; k++){LED_3.setPixelColor(k, red);} LED_3.show(); } if(i==3){ for(int k=0; k<LED_COUNT; k++){LED_4.setPixelColor(k, red);} LED_4.show(); } if(i==4){ for(int k=0; k<LED_COUNT; k++){LED_5.setPixelColor(k, red);} LED_5.show(); } if(i==5){ for(int k=0; k<LED_COUNT; k++){LED_6.setPixelColor(k, red);} LED_6.show(); } if(i==6){ for(int k=0; k<LED_COUNT; k++){LED_7.setPixelColor(k, red);} LED_7.show(); } if(i==7){ for(int k=0; k<LED_COUNT; k++){LED_8.setPixelColor(k, red);} LED_8.show(); } } // if(color_state[i]==1){ if(i==0){ for(int k=0; k<LED_COUNT; k++){LED_1.setPixelColor(k, yellow);} LED_1.show(); } if(i==1){ for(int k=0; k<LED_COUNT; k++){LED_2.setPixelColor(k, yellow);} LED_2.show(); } if(i==2){ for(int k=0; k<LED_COUNT; k++){LED_3.setPixelColor(k, yellow);} LED_3.show(); } if(i==3){ for(int k=0; k<LED_COUNT; k++){LED_4.setPixelColor(k, yellow);} LED_4.show(); } if(i==4){ for(int k=0; k<LED_COUNT; k++){LED_5.setPixelColor(k, yellow);} LED_5.show(); } if(i==5){ for(int k=0; k<LED_COUNT; k++){LED_6.setPixelColor(k, yellow);} LED_6.show(); } if(i==6){ for(int k=0; k<LED_COUNT; k++){LED_7.setPixelColor(k, yellow);} LED_7.show(); } if(i==7){ for(int k=0; k<LED_COUNT; k++){LED_8.setPixelColor(k, yellow);} LED_8.show(); } } // if(color_state[i]==2){ if(i==0){ for(int k=0; k<LED_COUNT; k++){LED_1.setPixelColor(k, blue);} LED_1.show(); } if(i==1){ for(int k=0; k<LED_COUNT; k++){LED_2.setPixelColor(k, blue);} LED_2.show(); } if(i==2){ for(int k=0; k<LED_COUNT; k++){LED_3.setPixelColor(k, blue);} LED_3.show(); } if(i==3){ for(int k=0; k<LED_COUNT; k++){LED_4.setPixelColor(k, blue);} LED_4.show(); } if(i==4){ for(int k=0; k<LED_COUNT; k++){LED_5.setPixelColor(k, blue);} LED_5.show(); } if(i==5){ for(int k=0; k<LED_COUNT; k++){LED_6.setPixelColor(k, blue);} LED_6.show(); } if(i==6){ for(int k=0; k<LED_COUNT; k++){LED_7.setPixelColor(k, blue);} LED_7.show(); } if(i==7){ for(int k=0; k<LED_COUNT; k++){LED_8.setPixelColor(k, blue);} LED_8.show(); } } // if(color_state[i]==3){ if(i==0){ for(int k=0; k<LED_COUNT; k++){LED_1.setPixelColor(k, green);} LED_1.show(); } if(i==1){ for(int k=0; k<LED_COUNT; k++){LED_2.setPixelColor(k, green);} LED_2.show(); } if(i==2){ for(int k=0; k<LED_COUNT; k++){LED_3.setPixelColor(k, green);} LED_3.show(); } if(i==3){ for(int k=0; k<LED_COUNT; k++){LED_4.setPixelColor(k, green);} LED_4.show(); } if(i==4){ for(int k=0; k<LED_COUNT; k++){LED_5.setPixelColor(k, green);} LED_5.show(); } if(i==5){ for(int k=0; k<LED_COUNT; k++){LED_6.setPixelColor(k, green);} LED_6.show(); } if(i==6){ for(int k=0; k<LED_COUNT; k++){LED_7.setPixelColor(k, green);} LED_7.show(); } if(i==7){ for(int k=0; k<LED_COUNT; k++){LED_8.setPixelColor(k, green);} LED_8.show(); } } // if(color_state[i]==4){ if(i==0){ for(int k=0; k<LED_COUNT; k++){LED_1.setPixelColor(k, purple);} LED_1.show(); } if(i==1){ for(int k=0; k<LED_COUNT; k++){LED_2.setPixelColor(k, purple);} LED_2.show(); } if(i==2){ for(int k=0; k<LED_COUNT; k++){LED_3.setPixelColor(k, purple);} LED_3.show(); } if(i==3){ for(int k=0; k<LED_COUNT; k++){LED_4.setPixelColor(k, purple);} LED_4.show(); } if(i==4){ for(int k=0; k<LED_COUNT; k++){LED_5.setPixelColor(k, purple);} LED_5.show(); } if(i==5){ for(int k=0; k<LED_COUNT; k++){LED_6.setPixelColor(k, purple);} LED_6.show(); } if(i==6){ for(int k=0; k<LED_COUNT; k++){LED_7.setPixelColor(k, purple);} LED_7.show(); } if(i==7){ for(int k=0; k<LED_COUNT; k++){LED_8.setPixelColor(k, purple);} LED_8.show(); } } } } int first_state(){ byte i; for(i=0; i<LED_COUNT; i++){ LED_1.setPixelColor(i, red); LED_2.setPixelColor(i, red); LED_3.setPixelColor(i, red); LED_4.setPixelColor(i, red); LED_5.setPixelColor(i, red); LED_6.setPixelColor(i, red); LED_7.setPixelColor(i, red); LED_8.setPixelColor(i, red); LED_1.show(); LED_2.show(); LED_3.show(); LED_4.show(); LED_5.show(); LED_6.show(); LED_7.show(); LED_8.show(); } } int off_state(){ byte i; for(i=0; i<LED_COUNT; i++){ LED_1.setPixelColor(i, off); LED_2.setPixelColor(i, off); LED_3.setPixelColor(i, off); LED_4.setPixelColor(i, off); LED_5.setPixelColor(i, off); LED_6.setPixelColor(i, off); LED_7.setPixelColor(i, off); LED_8.setPixelColor(i, off); LED_1.show(); LED_2.show(); LED_3.show(); LED_4.show(); LED_5.show(); LED_6.show(); LED_7.show(); LED_8.show(); } } int get_memory(){ for(int i=0;i<8;i++){ win_state[i] = EEPROM[i]; delay(10); } } int take_memory(){ for(int i=0;i<8;i++){ EEPROM[i]=color_state[i]; delay(10); } Serial.println("New comb in memory"); delay(300);softReset(); } void softReset(){asm volatile ("jmp 0");}Ну, да, распашка, только не такая простая, как я думал.
Скажи, пожалуйста, у тебя всё правильно подключено - именно к тем пинам, которые написаны в скетче? Например, в строке №60? Именно к этим пинам всё и подключено?
Уверен?
Ну, да, распашка, только не такая простая, как я думал.
Скажи, пожалуйста, у тебя всё правильно подключено - именно к тем пинам, которые написаны в скетче? Например, в строке №60? Именно к этим пинам всё и подключено?
Уверен?
Да, уверен.
Dfplayer'у нужен только tx для работы, назад он не возвращает инфы, кроме busy пина.
А 99 это рандом зачение. Компилятор кушает, плеер работает, все довольны)
В общем так, ошибку я тебе указал. Посмотри как устроен софтверный сериал и, если внимательно посмотришь, то поймёшь, что он при твоём "рандоме" он может гадить тебе на любой пин или вообще в любой IO порт. А может и не гадить - как повезёт. В какой именно порт (и гадит ли вообще) зависит от того, что ещё в программе написано - что ты, собственно и наблюдаешь.
Впрочем, если все довольны, то можешь и не смотреть, просто закрой тему. Чего воду в ступе толочь, если ты доволен?
Чего воду в ступе толочь, если ты доволен?
Вопрос то был не про то, что я доволен.
За помощь спасибо, не знал этого нюанса с сериал. Изучу .
Видимо, до этого мне часто везло, раз не всплывало.
В понедельник попробую, отпишусь.
Нашел инфу тут.
https://forum.arduino.cc/index.php?topic=112013.0
Может, кому понадобится, там вроде допилили библиотеку только на прием или только на передачу.
За помощь спасибо, не знал этого нюанса с сериал.
Ты так ни в чём и не разобрался, а, значит, проблема ждёт в засаде до следующего случая. Это вовсе не "нюанс с сериал". Это нюанс использования левых (особенно больших) чисел в место номера пина.
Я ж тебе писал "внимательно посмотри как устроен сериал". Ты этого либо не сделал, либо не разобрался в чём именно проблема. Если не можешь разобраться - спрашивай.
За помощь спасибо, не знал этого нюанса с сериал.
Ты так ни в чём и не разобрался, а, значит, проблема ждёт в засаде до следующего случая. Это вовсе не "нюанс с сериал". Это нюанс использования левых (особенно больших) чисел в место номера пина.
Я ж тебе писал "внимательно посмотри как устроен сериал". Ты этого либо не сделал, либо не разобрался в чём именно проблема. Если не можешь разобраться - спрашивай.
Попытка понять твою мысль пока не вышла успехом.
Попробую пояснить, что и как я искал, если ошибся - буду благодарен, если укажешь.
Из работы софт сериал я понял, что он устанавливает моё "рандом значение" как порт INPUT.
void SoftwareSerial::setRX(uint8_t rx) { pinMode(rx, INPUT); if (!_inverse_logic) digitalWrite(rx, HIGH); // pullup for normal logic! _receivePin = rx; _receiveBitMask = digitalPinToBitMask(rx); uint8_t port = digitalPinToPort(rx); _receivePortRegister = portInputRegister(port); }Далее логично посмотреть, что будет, если установить вместо номера порта "рандом значение". (Об этом ты мне написал утром.) Да и вообще pinMode в целом.
Далее инфа взята отсюда: https://garretlab.web.fc2.com/en/arduino/inside/hardware/arduino/avr/cores/arduino/wiring_digital.c/pinMode.html
А именно, при вызове pinMode происходит проверка "на адекватность":
void pinMode(uint8_t pin, uint8_t mode) { uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); volatile uint8_t *reg, *out; if (port == NOT_A_PIN) return;Каким образом? - Вызовом макроса digitalPinToPort(pin);
Как он работает? далее инфа отсюда: https://garretlab.web.fc2.com/en/arduino/inside/hardware/arduino/avr/cores/arduino/Arduino.h/digitalPinToPort.html
То есть он ищет значение в массиве
const uint8_t PROGMEM digital_pin_to_port_PGM[] = { PD, /* 0 */ PD, PD, PD, PD, PD, PD, PD, PB, /* 8 */ PB, PB, PB, PB, PB, PC, /* 14 */ PC, PC, PC, PC, PC, };И далее, если находит, продолжает работу, если нет, то, выходит, что команда pinMode игнорируется.
Поэтому я не могу понять, почему значение 99 может "гадить" в любой порт.
Буду благодарен, если пояснишь свою идею.
Всё же доступно. Игнорируется пинмоде или выдает на кой то пин можно проверить вставив контрольный вывод. Я где то натыкался внутри кода ардуиновского ядра, что нога с большим номером усекается на максимальное число ног до тех пор, пока не окажется в диапазоне 0 - мах и уже тогда применяется. Для какого чипа это было сделано я не помню, но в голове осталось, что опасно давать номера с большими числами, что бы не попасть на непонятный глюк.
У тебя изначально неверный подход. Вернее, начал ты правильно (с просмотра исходных кодов) Ну, так бы и продолжал. Причём здесь какой-то https://garretlab.web.fc2.com/? Самый достоверный источник инофрмации о программном коде - сам код, а вовсе не какие-то левые сайты.
Вот смотри, как это делается - именно это я имел в виду, когда говорил "посмотри внимательно":
Смотрим текст конструктора SoftwareSerial и видим:
Ага, смотрим текст setRX
void SoftwareSerial::setRX(uint8_t rx) { pinMode(rx, INPUT); if (!_inverse_logic) digitalWrite(rx, HIGH); // pullup for normal logic!теперь смотрим текст pinMode (потом можно и digitalWrite посмотреть). Итак, pinMode
void pinMode(uint8_t pin, uint8_t mode) { uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); volatile uint8_t *reg, *out; if (port == NOT_A_PIN) return;таак! А что ж у нас такое digitalPinToBitMask и digitalPinToPort и что там за NOT_A_PIN такой? Смотрим на них:
Ага. Ну, вот теперь всё понятно. digitalPinToPort - это просто чтение из прогмема по адресу digital_pin_to_port_PGM со смещением, равным номеру пина. А NOT_A_PIN - всего лишь ноль. Что мы прочитаем из байта с таким большим смещением? А хрен его знает, что там есть, то и прочитаем. Если там окажется ноль - сработает проверка на валидность. Если не ноль, то опять же смотря что. Если вдруг по адресу digital_pin_to_port_PGM + 99 вдруг окажется число, совпадающее с номером порта (любого DDRx/PORTx/PINx/etc.), а по адресу digital_pin_to_bit_mask_PGM + 99 окажется число от 0 до 7 включительно (а таковая вероятность есть - это как повезёт!!!), то мы получим "разумный адрес порта" в который и начнём радостно гадить!!!
Понятно? Собственно на этом можно и прекратить исследование, но если любопытно, то можно глянуть а куда же мы таки попадаем? Давай посмотрим. Для этого скомпилируем такой скетч, например, для Nano.
#include <Printing.h> void setup(void) { Serial.begin(9600); printVar((unsigned)(digital_pin_to_port_PGM + 99)); printVar((unsigned)(digital_pin_to_bit_mask_PGM + 99)); } void loop(void) {} // Результат в мониторе порта // (unsigned)(digital_pin_to_port_PGM + 99)=223 // (unsigned)(digital_pin_to_bit_mask_PGM + 99)=203Теперь запустим objdump на наш скомпилированный скетч:
Ну, что digital_pin_to_port_PGM мы видим и видим, что она нормальная, а вот со смещением 99 (по адрес DF) мы видим уже просто область кода - библиотечные коды там. Какие именно коды - а зависит от того, что мы у себя используем.
Вот так оно и получается.
На том сайте, на который я ссылался, довольно не плохо, на мой взгляд, расписано.
Но да, соглашусь, исходники лучше.
Большое спасибо за пояснения и пример, в этом вопросе разобрался. Было интересно)
По теме поста: ошибку с пином исправил - не спасло; поставил мегу и всё работает как надо.
Спасибо всем, кто отписался!