Сдвиговый регистр и 10 светодиодов
- Войдите на сайт для отправки комментариев
Всем добра!
Делаю пульт управления для радио модели, в пульте буду использовать 10 сегментный светодиодный индикатор для индикации уровня заряда. С ним будут работать 2 сдвиговых регистра 74HC595. Проблема в том что не могу заставить второй регистр работать последовательно после первого, он всё время его отзеркаливает. так же не понятно как мне объяснить второму регистру что нужно использовать только 2 пина.
я думаю для местных ветеранов вопрос плёвый, подсобите пожалуйста.
методом проб и ошибок при помощи датчика освещенности загораются последовательно два светодиода подключённых к второму регистру, за ними последовательно 2 светодиода первого регистра, но остальные 6 диодов подключенных к первому регистру не горят, помогите превратить эту кашу в нормальный код.
==============================
http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
1. Код не по правилам (за три года не научился?)
2. Схему в студию))
Для начала выводите в цепочку просто цифровые значения от 1 до 2^10. Индикатор должен начать отображать двоичный код. Если такого не происходит - схема собрана неправильно. О чем так же свидетельствует фраза "так же не понятно как мне объяснить второму регистру что нужно использовать только 2 пина."
Но, так как схема в посте отсутствует, то проверить ее мы не можем.
Во первых - вставьте программу по правилам форума.
Во вторых - зачем Вы 2 раза считываете А1, если distance1=distance?
В третьих - а выдать значения после map() не судьба? Посмотреть какая там херня получается.
Но, так как схема в посте отсутствует, то проверить ее мы не можем.
А ХШ?
sharkman89,
суда по вот этому посту, В умеете вставлять скетч. Значит, здесь просто поиздевались :-(
Но, так как схема в посте отсутствует, то проверить ее мы не можем.
А ХШ?
Сдал Мурашке с Голиковой - им нужнее.
const int SER=2; const int LATCH =4; const int CLK =3; // Контакт дпя подключения вывода CLOCK const int DIST=0; int vals[9] = {0,1,3,7,15,31,63,127,255}; int vals1[3] = {0,1,3}; // Максимальное значение расстояния int maxVal = 719; int minVal = 150; int maxVal1 = 750; int minVal1 = 720; void setup() { // Установить контакты на вывод (OUTPUT) pinMode(SER, OUTPUT); pinMode(LATCH, OUTPUT); pinMode(CLK, OUTPUT); } void loop() { int distance = analogRead(A1); int distance1 = analogRead(A1); distance = map(distance, minVal, maxVal, 0 ,8); distance = constrain(distance,0,8); distance1 = map(distance1, minVal1, maxVal1, 0 ,2); distance1 = constrain(distance1,0,2); digitalWrite(LATCH, LOW); // LATCH - низкий - начало отправки shiftOut(SER, CLK, LSBFIRST, vals[distance]); // Старший бит - первый shiftOut(SER, CLK, MSBFIRST, vals[distance1]); digitalWrite(LATCH, HIGH); // LATCH - высокий delay (10); }спасибо за отклик, ардуино не мой основной заработок, по этому за 3 года которые я здесь числюсь к сожалению не смог стать профессиональным создателем скетчей, тем не менее все задачи которые себе ставлю решаю. может не так быстро и красиво как некоторые, но факт. здесь я так понял не раздел для новичков, а раздел для демотивации начинаний, еще раз спасибо за помощь!
А разницы между 34 и 35 строки ты не заметил?
void loop() { int distance = analogRead(A1); digitalWrite(LATCH, LOW); // LATCH - низкий - начало отправки shiftOut(SER, CLK, MSBFIRST, highByte(distance)); // Старший бит - первый shiftOut(SER, CLK, MSBFIRST, lowByte(distance)); digitalWrite(LATCH, HIGH); // LATCH - высокий delay (10); }Должно выводиться то, что считано из A1 в двоичном коде
ты имеешь в виду MSBFIRST и LSBFIRST? только при таком старшинстве битов последовательно загораются 2 светодиода второго регистра, а за ними 2 первого регистра.
Как насчет того. чтобы подумать, почему так?
буду думать.
а что шкала такая неравномерная?
Первый регистр - 569 единиц на 8 сегментов - по 71 единице на сегмент
Второй регистр - (750-720) =30 единиц на 2 сегмента - 15 на сегмент?
Не говоря уж о том, что идея делать map() для каждого регистра отдельно - бредовая. Сначала нужно преобразовать все число в нужный диапазон, а потом вывести на оба регистра разом, как показал Командир.
Добавлю, Ваша проблема в том, что похоже вы крайне плохо представляете битовые операции и работу сдвиговых регистров, почитайте что-нить об этом
Сначала нужно преобразовать все число в нужный диапазон, а потом вывести на оба регистра разом, как показал Командир.
Немного подумал - я не прав. Цитирую сам себя :) - вот эта фраза неверная. Вывод двоичного значения числа не даст нам последовательного загорания сегментов индикатора. Так что код Командира (формально правильный) для этой задачки не подходит. А вот в коде ТС видны проблески правильного подхода - у него задана табличка "правильных" значений для каждого диапазона.
Только. похоже, он это все где-то списал и пользоваться не умеет
b707 я не пытался выводить "как на индикатор уровня". Для этого надо старшую единицу "клонировать-вниз".
Для этого надо старшую единицу "клонировать-вниз".
для 10 градаций проще табличку составить :) как у ТС и задумано...
тонкой настройкой регистра я буду заниматься когда получу необходимый результат, по поводу моих познаний с битовыми операциями полностью с вами согласен, недостаточно изучил пока. именно по этому и обратился за помощью.
тонкой настройкой регистра я буду заниматься когда получу необходимый результат
без настройки не получите
всем спасибо, код заработал
const int SER=2; const int LATCH =4; const int CLK =3; // Контакт дпя подключения вывода CLOCK const int DIST=0; int vals[9] = {0,1,3,7,15,31,63,127,255}; int vals1[3] = {0,1,3}; // Максимальное значение расстояния int maxVal = 569; int minVal = 150; int maxVal1 = 750; int minVal1 = 570; void setup() { // Установить контакты на вывод (OUTPUT) pinMode(SER, OUTPUT); pinMode(LATCH, OUTPUT); pinMode(CLK, OUTPUT); } void loop() { int distance = analogRead(A1); int distance1 = analogRead(A1); distance = map(distance, minVal, maxVal, 0 ,8); distance = constrain(distance,0,8); distance1 = map(distance1, minVal1, maxVal1, 0 ,2); distance1 = constrain(distance1,0,2); digitalWrite(LATCH, LOW); // LATCH - низкий - начало отправки shiftOut(SER, CLK, LSBFIRST, vals[distance]); // Старший бит - первый shiftOut(SER, CLK, MSBFIRST, vals[distance1]); digitalWrite(LATCH, HIGH); // LATCH - высокий delay (10); }если у кого то есть предложения по оптимизации, буду благодарен!
если у кого то есть предложения по оптимизации, буду благодарен!
массив vals1[] не нужен. В коде он не используется
ну и про строчку 27 вам вроде говорили уже. Уберите второе чтение А1, вторую переменную для дистанции... это же бред.
вы правы, спасибо!
если я уберу 27ю строку. как будет происходить распределение массива?
c ней убирается 31,32
если я уберу 27ю строку. как будет происходить распределение массива?
c ней убирается 31,32
а вы не убирайте 31 и 32. У вас обе дистанции ведь равны? - так и напишите.
Читать лишний раз из analofRead() очень затратно по времени. Хотя в вашем случае это и не имеет значения - лучше не привыкать так делать.
На будущее - лучше использовать одну переменную дистанции. Но для этого нужно переписать работу с регистром на загрузку одного 16битного значения вместо двух восьмибитных, как у вас
Я бы сделал так:
void setup() { pinMode(MOSI, OUTPUT); pinMode(CLOCK, OUTPUT); } void write() { int value;// расчитаное значение, например через map(); for (int i=0;i<=9;i++) { digitalWrite(MOSI, (i==value)?1:0);//если нужна точка на шкале digitalWrite(MOSI, (i<=value)?1:0);//если нужен столбик на шкале digitalWrite(CLOCK,1); digitalWrite(CLOCK,0); } }Благодарю
Так у вас еще 6 разрядов гуляют без дела их тоже можно загрузить если есть необходимость
Да, но пока в этом необходимости нет
Так у вас еще 6 разрядов гуляют без дела их тоже можно загрузить если есть необходимость
не можно, а нужно.
Если у вас 2 регистра по 8 бит - надо всегда обязательно грузить все 16 разрядов, иначе ерунда выйдет
В чём именно может выразиться ерунду?
почитайте как работает регистр, а потом подумайте, что будет в "лишних" разрядах после "задвигания" нового значения.
Хотя если у вас физически к остальным пинам ничего не подключено - то не страшно