Манипуляции с массивами. Помогите найти ошибку
- Войдите на сайт для отправки комментариев
Помогите найти ошибку - уже второй день бьюсь над тремя строчками.
Чтобы был чуть понятнее контекст:
Делается систма управления светодиодной биколорной матрицы с результирующим разрешением 8х32. Матрица состоит из физических матриц 8х8.
Изображение кодируется 8 наборами (8 строк) по 8 байт (4 "красных" и 4 "зеленых" байта, байты цветов - чередуются). Изменить это нельзя - управление идет с помощью цепочки сдвиговых регистров (схема уже есть и работает).
Сейчас делаю "бегущую строку" (и именно с ней и проблема). Логика работы проста:
1. Есть массив array[8][8] - его отображаем
2. Есть массив shadow[8][8] - это то, что должно "выползти"
3. Прогоняем в цикле "сдвиг" обоих массивов влево и по необходимости дополняем массив array данными из массива shadow
Таким образом, после завершения "прогона" результирующий массив arrow должен сравняться с исходным массивом shadow.
Выкинул из скетча все лишнее - оставил только "сдвиг":
#define RED 0 #define GREEN 1 #define YELLOW 2 byte array[8][8] = { // Массив из 64 байт {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B10000000, B00000001}, // строка 7 {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B01000000, B00000010}, // строка 6 {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00100000, B00000100}, // строка 5 {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00010000, B00001000}, // строка 4 {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00001000, B00010000}, // строка 3 {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000100, B00100000}, // строка 2 {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000010, B01000000}, // строка 1 {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001, B10000000} // строка 0 // red3 green3 red2 green2 red1 green1 red0 green0 // b0 b1 b2 b3 b4 b5 b6 b7 }; byte shadow[8][8] = { // Массив из 64 байт {B10000000, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}, // строка 7 {B01000000, B00000010, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}, // строка 6 {B00100000, B00000100, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}, // строка 5 {B00010000, B00001000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}, // строка 4 {B00001000, B00010000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}, // строка 3 {B00000100, B00100000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}, // строка 2 {B00000010, B01000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}, // строка 1 {B00000001, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000} // строка 0 // red3 green3 red2 green2 red1 green1 red0 green0 }; void setup(){ int i, j, k; Serial.begin(9600); printArray(); printShadow(); for(k=0; k<32; k++){ // проходим 32 шага - чтобы самый крайний правый пиксель уехал влево до конца for(j=0; j<8; j++){ // перебираем столбцы (начинаем с самого левого) for(i=0; i<8; i++){ // строки (с нулевой) array[i][j]=array[i][j]<<1; // сдвигаем байты основного массива на 1 (старший бит - теряется, младший - 0) // заполняем младший бит текущего байта if(j<6){ // если требуемый байт в рамках основного массива // берем старший бит из предыдущего байта нужного цвета bitWrite(array[i][j],0,bitRead(array[i][j+2],7)); } else { // если в текущем массиве нет нужного байта (за границей массива) // берем из начала теневого массива (подтягиваем теневой массив) if(j==6){ // "красный" байт bitWrite(array[i][6],0,bitRead(shadow[i][0],7)); } else { // "зеленый" байт bitWrite(array[i][7],0,bitRead(shadow[i][1],7)); } } // теневой массив тоже сдвигаем shadow[i][j]=shadow[i][j]<<1; if(j<6){ bitWrite(shadow[i][j],0,bitRead(shadow[i][j+2],7)); } } } Serial.println("-----------------------------------------------"); Serial.print("k="); Serial.println(k); printArray(); printShadow(); } } void loop(){ } // печатем основной массив void printArray() { Serial.println("----- array -----"); for(byte color=RED; color<YELLOW; color++){ Serial.println((color)?"GREEN":"RED"); for(int i=0; i<8; i++){ for(int j=color; j<8; j=j+2) { for(int k=7; k>=0; k--){ Serial.print(bitRead(array[i][j], k), DEC); } Serial.print(" "); } Serial.println(); } Serial.println(); } } // печатем теневой массив void printShadow() { Serial.println("----- shadow ------"); for(byte color=RED; color<YELLOW; color++){ Serial.println((color)?"GREEN":"RED"); for(int i=0; i<8; i++){ for(int j=color; j<8; j=j+2) { for(int k=7; k>=0; k--){ Serial.print(bitRead(shadow[i][j], k), DEC); } Serial.print(" "); } Serial.println(); } Serial.println(); } }
В коде специально оставил пару отладочных функций для печати массива - чтобы наглядно можно было отследить.
Сам сдвиг работает, но есть ошибка, которую я никак не могу отловить (находится скорее всего в выделенных строках или в условии чуть выше).
В массиве специально завел "единички" по диагонали - чтобы при сдвиге было просто увидеть, как работает скетч.
Проблема в том, что при k=0 - из теневого массива вытягиваются неправильные данные:
----- array ----- RED 00000000 00000000 00000001 00000000 00000000 00000000 00000000 10000001 00000000 00000000 00000000 01000000 00000000 00000000 00000000 00100000 00000000 00000000 00000000 00010000 00000000 00000000 00000000 00001000 00000000 00000000 00000000 00000100 00000000 00000000 00000000 00000010 GREEN 00000000 00000000 00000000 00000010 00000000 00000000 00000000 00000100 00000000 00000000 00000000 00001000 00000000 00000000 00000000 00010000 00000000 00000000 00000000 00100000 00000000 00000000 00000000 01000000 00000000 00000000 00000000 10000001 00000000 00000000 00000001 00000000
Видно, что исходные "\" и "/" в массиве сдвинулись на 1 позицию влево, но из теневого массива почему-то подтянулись неправильные данные (в "красном" массиве самая правая единичка должна быть сверху, а не во второй строке, в "зеленом" - соответственно в самом нижнем должна быть).
Помогите найти ошибку, пожалуйста.
Проблема не в выделенных строках, а в логике цикла.
Если внимательно всмотреться в код станет понятно, что первый столбец теневого массива сдвигается раньше, чем последний столбец исходного. Таким образом, к моменту сдвига последнего столбца исходного массива, в первом столбце теневого (откуда должны браться данные), данные уже сдвинуты. В итоге из теневого массива берется бит, который изначально был вторым. Что неверно.
Сдвиг теневого массива нужно вынести из цикла по j в самостоятельный цикл. Оставив его, при этом, внутри цикла по k.
Спасибо! Тоже уже до этого дошел. Правда, сдвиг теневого массива оставил, где он есть, но обернул его условием, чтобы выполнялся при k>0
Судя по выводу в сериал.монитор - работает правильно, но, может, я чего-то не замечаю?
Так тоже должно работать.
Но в итоге shadow окажется недосдвинутым на 1 пиксель. Если эта особенность не смущает, то и проблем нет, хотя ясности программе это не добавит -)
особенность не смущает - во всех последующих вызовах shadow предварительно "зачищается".
Попробовал вынести из цикла и запутался еще больше (не получилось), подскажите, как это в коде должно выглядеть?
Сорри, пишу на бегу, подробно не получиться, но примерно должно выглядеть так: