Пины и EEPROM

Hatber
Offline
Зарегистрирован: 10.04.2020

Всем доброго дня!
Работаю над одним проектом, суть которого заключается в том, что надо управлять 8 отдельными лентами с адресными светодиодами WS2812B.
Для этого использую 8 различных пинов Ардуино (со второго по одиннадцатый) и библиотеку NeoPixel.
Все хорошо работало и ничего не предвещало головняка, пока не потребовалось доработка.
Добавилась запись определенных переменных в энергонезависимую память.
С записью/чтением все хорошо.
НО
отвалилось управление лентой на 11 пине.
Пробовал много различных вариантов и проверок (это далеко не первый мой проект), но с таким встречаюсь впервые. Добавляею функцию с запись в память - нет управления ленты, убираешь функцию с памятью - все ок.

Отсюда вопрос: влияет ли работа библиотеки EEPROM на какие либо пины?
Ну или может кто подскажет, в какую сторону копать, так как перепаять на другой пин уже довольно проблематично. Да и вообще хочу понять, в чем дело.

Hatber
Offline
Зарегистрирован: 10.04.2020

Поправка: с четвертого по 11 пин.
Ардуино нано использую.

rkit
Offline
Зарегистрирован: 23.11.2016

Не влияет. Копать в сторону внимательного чтения кода.

b707
Offline
Зарегистрирован: 26.05.2017

возможно не хватает памяти. Восемь адрессных лент  (какой длины?) на Нано - это может быть много.

Hatber
Offline
Зарегистрирован: 10.04.2020

Код перечитал, увы. Видимо, что то упускаю

Hatber
Offline
Зарегистрирован: 10.04.2020

По 200 диодов на каждой.
В память записываются 8 чисел (значения от о до 4 каждое) в восемь ячеек, соответственно.

sadman41
Offline
Зарегистрирован: 19.10.2016

Возьмите ардуину побольше.

b707
Offline
Зарегистрирован: 26.05.2017

Hatber пишет:
По 200 диодов на каждой. В память записываются 8 чисел (значения от о до 4 каждое) в восемь ячеек, соответственно.

Если цветовая картинка на каждой ленте своя, то это выходит 200 * 8 * 3 = 4800 байт, что абсолютно нереально для Нано

Если картинка одинаковая на все 8 лент - то как вы копируете сигнал с одного пина на 7 других?

Hatber
Offline
Зарегистрирован: 10.04.2020

Теперь самому стало интересно, как оно работало)
Каждая лента целиком горит одним из 5 цветов.
Цвета в ленте меняются с помощью цикла, в котором применяется цвет для n-го диода каждой из 8ми лент и отправляется команда зажечь его.
То есть лента загораются не одновременно, а по одному диоду, но быстро.
Возможно, оно работало поэтому.

sadman41
Offline
Зарегистрирован: 19.10.2016

Судя по развитию событий - без черной магии тут не обошлось.

Hatber
Offline
Зарегистрирован: 10.04.2020

Там все запаковано уже, с защитой от темных сил)
Ардуино побольше взять = перепаять все, чего хотелось бы избежать.
Но если не найду причин до понедельника, то, видимо, придется взять что то с большей памятью и пробовать.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

Судя по развитию событий - без черной магии тут не обошлось.

нее, ту жеж сразу видно - шаман, а это Практическая магия )))

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Мля, мы скетч когда-нибудь увидим?

А заодно проверку памяти в нём?

Или так и будем языком по ягодицам шлёпать?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

sadman41 пишет:

Судя по развитию событий - без черной магии тут не обошлось.

Да, какая нахрен магия - стек пропорол кучу и началось веселье. "Вот тут вроде работает, а запятую поменял - всё свалилось нахрен". Впервой, что ли?

Hatber
Offline
Зарегистрирован: 10.04.2020

Ворота пишет:

sadman41 пишет:

Судя по развитию событий - без черной магии тут не обошлось.

Да, какая нахрен магия - стек пропорол кучу и началось веселье. "Вот тут вроде работает, а запятую поменял - всё свалилось нахрен". Впервой, что ли?

Очень на это похоже.
Скажем так, не часто с таким сталкивался, а на Ардуино первый раз. И в голову не пришло в ту сторону копать)
За идею спасибо.
Но тут у меня опыта маловато.
Есть какие-либо варианты вылечить?
На ум пока приходит только какой-либо костыль типа очищения памяти после отправки в ленту (скорее всего чушь спорол, но хз)

Hatber
Offline
Зарегистрирован: 10.04.2020

Ворота пишет:

Мля, мы скетч когда-нибудь увидим?

А заодно проверку памяти в нём?

Или так и будем языком по ягодицам шлёпать?


Как до ноута доберусь, скину.
Думаю, ближе к вечеру.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Hatber пишет:
Есть какие-либо варианты вылечить?
Мужик, ты вообще читаешь, чё те пишут?

Ворота пишет:

Мля, мы скетч когда-нибудь увидим? А заодно проверку памяти в нём? Или так и будем языком по ягодицам шлёпать?

Hatber
Offline
Зарегистрирован: 10.04.2020

Видел, говорю ж, чуть ближе к вечеру.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

ну, таком разе "думаю, ближе к вечеру" и поговорим. А сейчас говорить не о чем.

Только ты уж сразу там и на память посмотри MemoryExplorer'ом. Библиотеку можно взять здесь.

sadman41
Offline
Зарегистрирован: 19.10.2016

Если гражданин уверяет, что на его nano точно работала конфигурация, которая требует 5кб рамы, то никакого стека тут нет - исключительно черная магия.

Hatber
Offline
Зарегистрирован: 10.04.2020

MemoryExplorer сказал следующее:

 ---- Memory report: Fragmentation
HEAP:@048A(1162)-@0877(2167);
Unallocated from:@06E4(1764);
Stack pointer: @08F7(2295)
Free List: EMPTY
-----
 
Собственно, сам код
Для уточнения дополню:
8 кнопок управляет 8ю лентами (каждая кнопка своей лентой). Эдакая мини-игрушка, цель которой выставить нужные цвета. Когда выставил - срабатывает реле.

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");} 

 

 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Ну, да, распашка, только не такая простая, как я думал.

Скажи, пожалуйста, у тебя всё правильно подключено - именно к тем пинам, которые написаны в скетче? Например, в строке №60? Именно к этим пинам всё и подключено?

Уверен?

Hatber
Offline
Зарегистрирован: 10.04.2020

Ворота пишет:

Ну, да, распашка, только не такая простая, как я думал.

Скажи, пожалуйста, у тебя всё правильно подключено - именно к тем пинам, которые написаны в скетче? Например, в строке №60? Именно к этим пинам всё и подключено?

Уверен?


Да, уверен.
Dfplayer'у нужен только tx для работы, назад он не возвращает инфы, кроме busy пина.
А 99 это рандом зачение. Компилятор кушает, плеер работает, все довольны)

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Hatber пишет:
все довольны)
Точно все? Или таки не все? Ты, вот, похоже, не доволен,  иначе зачем этот пост?

В общем так, ошибку я тебе указал. Посмотри как устроен софтверный сериал и, если внимательно посмотришь, то поймёшь, что он при твоём "рандоме" он может гадить тебе на любой пин или вообще в любой IO порт. А может и не гадить - как повезёт. В какой именно порт (и гадит ли вообще) зависит от того, что ещё в программе написано - что ты, собственно и наблюдаешь.

Впрочем, если все довольны, то можешь и не смотреть, просто закрой тему. Чего воду в ступе толочь, если ты доволен?

Hatber
Offline
Зарегистрирован: 10.04.2020

Ворота пишет:

 

Hatber пишет:
все довольны)

Чего воду в ступе толочь, если ты доволен?

Вопрос то был не про то, что я доволен.

За помощь спасибо, не знал этого нюанса с сериал. Изучу .

Видимо, до этого мне часто везло, раз не всплывало.

В понедельник попробую, отпишусь.

 

Hatber
Offline
Зарегистрирован: 10.04.2020

Нашел инфу тут.

https://forum.arduino.cc/index.php?topic=112013.0

Может, кому понадобится, там вроде допилили библиотеку только на прием или только на передачу.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Hatber пишет:

За помощь спасибо, не знал этого нюанса с сериал.

Ты так ни в чём и не разобрался, а, значит, проблема ждёт в засаде до следующего случая. Это вовсе не "нюанс с сериал". Это нюанс использования левых (особенно больших) чисел в место номера пина.

Я ж тебе писал "внимательно посмотри как устроен сериал". Ты этого либо не сделал, либо не разобрался в чём именно проблема. Если не можешь разобраться - спрашивай.

Hatber
Offline
Зарегистрирован: 10.04.2020

Ворота пишет:

Hatber пишет:

За помощь спасибо, не знал этого нюанса с сериал.

Ты так ни в чём и не разобрался, а, значит, проблема ждёт в засаде до следующего случая. Это вовсе не "нюанс с сериал". Это нюанс использования левых (особенно больших) чисел в место номера пина.

Я ж тебе писал "внимательно посмотри как устроен сериал". Ты этого либо не сделал, либо не разобрался в чём именно проблема. Если не можешь разобраться - спрашивай.

Попытка понять твою мысль пока не вышла успехом. 

Попробую пояснить, что и как я искал, если ошибся - буду благодарен, если укажешь.

Из работы софт сериал я понял, что он устанавливает моё "рандом значение" как порт 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 может "гадить" в любой порт.

Буду благодарен, если пояснишь свою идею.

nik182
Offline
Зарегистрирован: 04.05.2015

Всё же доступно. Игнорируется пинмоде или выдает на кой то пин можно проверить вставив контрольный вывод. Я где то натыкался внутри кода ардуиновского ядра, что нога с большим номером усекается на максимальное число ног до тех пор, пока не окажется в диапазоне 0 - мах и уже тогда применяется. Для какого чипа это было сделано я не помню, но в голове осталось, что опасно давать номера с большими числами, что бы не попасть на непонятный глюк.   

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

У тебя изначально неверный подход. Вернее, начал ты правильно (с просмотра исходных кодов) Ну, так бы и продолжал. Причём здесь какой-то  https://garretlab.web.fc2.com/? Самый достоверный источник инофрмации о программном коде - сам код, а вовсе не какие-то левые сайты.

Вот смотри, как это делается - именно это я имел в виду, когда говорил "посмотри внимательно":

Смотрим текст конструктора SoftwareSerial и видим:

SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) : 
 ...
  setRX(receivePin); 

Ага, смотрим текст 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 такой? Смотрим на них:

#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
...
#define NOT_A_PIN 0
#define NOT_A_PORT 0

Ага. Ну, вот теперь всё понятно. 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 на наш скомпилированный скетч:

0000007c <digital_pin_to_port_PGM>:
  7c:	04 04 04 04 04 04 04 04 02 02 02 02 02 02 03 03     ................
  8c:	03 03 03 03                                         ....

00000090 <__ctors_start>:
  90:	a6 00       	.word	0x00a6	; ????
  92:	56 02       	muls	r21, r22

00000094 <__ctors_end>:
  94:	11 24       	eor	r1, r1
  96:	1f be       	out	0x3f, r1	; 63
  98:	cf ef       	ldi	r28, 0xFF	; 255
  9a:	d8 e0       	ldi	r29, 0x08	; 8
  9c:	de bf       	out	0x3e, r29	; 62
  9e:	cd bf       	out	0x3d, r28	; 61

000000a0 <__do_copy_data>:
  a0:	11 e0       	ldi	r17, 0x01	; 1
  a2:	a0 e0       	ldi	r26, 0x00	; 0
  a4:	b1 e0       	ldi	r27, 0x01	; 1
  a6:	e0 ef       	ldi	r30, 0xF0	; 240
  a8:	fa e0       	ldi	r31, 0x0A	; 10
  aa:	02 c0       	rjmp	.+4      	; 0xb0 <__do_copy_data+0x10>
  ac:	05 90       	lpm	r0, Z+
  ae:	0d 92       	st	X+, r0
  b0:	a4 37       	cpi	r26, 0x74	; 116
  b2:	b1 07       	cpc	r27, r17
  b4:	d9 f7       	brne	.-10     	; 0xac <__do_copy_data+0xc>

000000b6 <__do_clear_bss>:
  b6:	22 e0       	ldi	r18, 0x02	; 2
  b8:	a4 e7       	ldi	r26, 0x74	; 116
  ba:	b1 e0       	ldi	r27, 0x01	; 1
  bc:	01 c0       	rjmp	.+2      	; 0xc0 <.do_clear_bss_start>

000000be <.do_clear_bss_loop>:
  be:	1d 92       	st	X+, r1

000000c0 <.do_clear_bss_start>:
  c0:	a4 32       	cpi	r26, 0x24	; 36
  c2:	b2 07       	cpc	r27, r18
  c4:	e1 f7       	brne	.-8      	; 0xbe <.do_clear_bss_loop>

000000c6 <__do_global_ctors>:
  c6:	10 e0       	ldi	r17, 0x00	; 0
  c8:	ca e4       	ldi	r28, 0x4A	; 74
  ca:	d0 e0       	ldi	r29, 0x00	; 0
  cc:	04 c0       	rjmp	.+8      	; 0xd6 <__do_global_ctors+0x10>
  ce:	21 97       	sbiw	r28, 0x01	; 1
  d0:	fe 01       	movw	r30, r28
  d2:	0e 94 dd 03 	call	0x7ba	; 0x7ba <__tablejump2__>
  d6:	c8 34       	cpi	r28, 0x48	; 72
  d8:	d1 07       	cpc	r29, r17
  da:	c9 f7       	brne	.-14     	; 0xce <__do_global_ctors+0x8>
  dc:	0e 94 27 03 	call	0x64e	; 0x64e <main>
  e0:	0c 94 76 05 	jmp	0xaec	; 0xaec <_exit>

000000e4 <__bad_interrupt>:
  e4:	0c 94 00 00 	jmp	0	; 0x0 <__vectors>

000000e8 <setup>:
  e8:	26 e0       	ldi	r18, 0x06	; 6
  ea:	40 e0       	ldi	r20, 0x00	; 0
  ec:	51 ee       	ldi	r21, 0xE1	; 225
  ee:	60 e0       	ldi	r22, 0x00	; 0

Ну, что digital_pin_to_port_PGM мы видим и видим, что она нормальная, а вот со смещением 99 (по адрес DF) мы видим уже просто область кода - библиотечные коды там. Какие именно коды - а зависит от того, что мы у себя используем.

Вот так оно и получается.

Hatber
Offline
Зарегистрирован: 10.04.2020

На том сайте, на который я ссылался, довольно не плохо, на мой взгляд, расписано.

Но да, соглашусь, исходники лучше.

Большое спасибо за пояснения и пример, в этом вопросе разобрался. Было интересно)

 

По теме поста: ошибку с пином исправил - не спасло; поставил мегу и всё работает как надо.

Спасибо всем, кто отписался!