Хм.. по этому логу происходит ровно одно включение 13-того пина, и ровно одно выключение.
Я вижу три варианта:
Вы дали лог не целиком. Ниже, если проскролить, еще что-то есть.
Диод включается не скетчем, а где-то в схеме подключения "гуляет" лишние питание.
Вы внесли какие-то поправки в скетч, и где-то есть место, где диод включается без рапорта в serial.
И кстати, я практически уверен что это лог когда вы нажатия отправляете не с другой дуины, а руками в Serial. Зачем мне лог ситуации когда "все работает правильно" (по вашим словам)? Мне нужен лог ситуации когда проблема есть в наличии. То ест когда "шлет другая". Когда проявляется "лишние включение".
P.S. В скайпе отправил вам запрос на авторизацию еще вчера, но пока вас не вижу Online.
Абсолютно правы.Я неправильно понял ваше"А что при этом видно в Serial Monitor у "принимающей"?"Прицепил принимающую дуину к сериал-монитору и руками подавал команды .В скетч не лазил, упаси Бог !
Поскольку порты у дуин заняты р/модулями, решил еще один модуль на той-же частоте повесить на сериал-монитор. И повключал первую кнопку. И..ни хрена не понял :все прекрасно один раз включается,горит 2 сек, выключается .Чудеса какие-то..Может, по ночам меньше сидеть надо? Но точно -же было,считал промежутки секундомером...
причем почему-то то два раза подряд пишет "11131100:Readed byttoIndex=0
131104:Readed byttoIndex=0,
то один раз.Светодиод загорается исправно в любом случае..
Спасибо,так действительно лучше.Сейчас попробую. Смущает только,что при последовательном соединении выход из строя светодиода нарушит работу модуля? Или это невероятно с их ресурсом?
На почте у меня пусто.Скайп включен, имя правильное...
Зачем же так? Если это ваше хобби, и вы хотите чему-то учится. Иметь возможность самому что-то делать - лазить в скетч НУЖНО. Эксперементировать, смотреть что получается (ну естественно после того как заработало минимальное). Как дети учатся. Берут и пробуют :)
>Поскольку порты у дуин заняты р/модулями, решил еще один модуль на той-же частоте повесить на сериал-монитор.
Честно говоря - ничего не понял. Я имел ввиду такое подключение: дуины соединяем крест-накрест, к принимающий подтыкиваем USB кабель, и на компе открываем Serial Monitor.
>причем почему-то то два раза подряд пишет "11131100:Readed byttoIndex=0
Эта надпись означает "что-то пришло от передающей", а та может и 10-ть раз слать. В зависимости от того сколько времени держите кнопку. Если вы не убирали delay(500), то будет слать каждые пол секунды (если кнопка нажата). Если убрать delay (или уменьшить) - гораздо чаще. У брать его будет нужно (если у вас скорости 300-400км/ч то эта пол.секундная задержка может играть рояль). И скорость порта, возможно, нужно будет поднять повыше чем 9600 (но это уже от ваших передатчиков зависит, на какой скорости они стабильно работают).
Но так как у нас есть проверка "игнорировать пока горит диод" - это ничему не мешает. Разве что эфир "забивается". Если это критично, то можно, на передающей, запоминать предыдущие состояния кнопок, и отсылать номер, только если "состояние изменилось". А не "пока держим".
То между собой они могут общатся масимум, на скорости 19200. Но зависит от растояния. Производитель обещает 9600 на растоянии 1.2км.
С самой ардуиной они могут общатся "побыстрее". До 57600.
Необходимости что-бы скосрости связи ардуино<->модуль и модуль<->модуль точно совпадали - скорее всего нет. Даже лучше будет если ардуино<->модуль будет на более высокой скорости чем модуль<->модуль.
Поэтому в скетчах я бы ставил скорость 28800 или 38400 (что-бы был запас). А сами модули соединял на 19200 и ниже (опытно подбирая на какой скорости они стабильно держут связь).
У вас и так стоят транзисторы на релейном блоке. Рядом с разЪемом 4 резистора на 1 кОм, даже при коротком замыкании транзистора при 5 вольтах на пине максимальный ток составит 5 мА. Вы как ток мериете? Случайно не между пином и землей?
"Вы как ток мериете? Случайно не между пином и землей?"
В разрыв плюса питания вставляю амперметр, измеряю потребление ардуины с модулем,затем подаю кнопкой сигнал на одну ногу, опять меряю , отнимаю одно от другого.Неправильно ?
Таким образом вы измеряете потребляемый ток дуины и самих реле, а не ток на ноге. Если хотите можете ради эксперемента померить ток на ноге, подключив амперметр в разрыв между пином и блоком реле, но уверяю вас ток будет маленьким. И если бы на ногах дуины были действительно такие токи, то МК сильно грелся и в итоге сгорел бы.
Да, большой емкости должны быть аккумуляторы, что бы работать на таких токах. В ощем при 3 амперах можно использовать обычные транзисторы, но прикрученных к радиатору. Но т.к. у вас уже есть блок реле, то пусть он и будет.
Время горения каждого цвета - около 30 сек за 1 гонку.Гонок в день-10-15 в лучшем случае.Думаю, немного.
Честно говоря ,сам хотел транзисторную сборку,нет контактов, быстрей, надежней.Но готовую не нашел, а тратить время на это нет смысла, пока не решены самые сложные для меня програмные проблемы комплекса...
Это не я решил. Это программер и просто хороший человек под ником "leshak " решил все мои програмные проблемы, связанные с беспроводным управлением светофором, являюшимся частью судейского комплекса,за что ему огромное спасибо от меня и других спортсменов -авиамоделистов .Теперь на базе его решения по аналогии(по другому пока не умею) буду городить весь судейский комплекс ,результаты-сюда. Буду рад любой помощи.Михаил
if(buttonIndex>=0 && buttonIndex<TOTAL_LEDS){ //игнорируем случайный мусор, если вдруг прийдет
if(!times_off[buttonIndex]){ // если диод уже выключен - игнорируем повторное нажатие кнопки. Выключаем только включенные
digitalWrite(LED_PINS[buttonIndex],LOW); //выключаем
Serial.print(millis());
Serial.print(":TurnOn");Serial.println(buttonIndex);
times_off[buttonIndex]=millis()+2000;// запоминаем время когда нужно будет включить
}
}
}
//проверяем, не настало-ли время включать
unsigned long currentTime=millis();
for(byte i=0;i<TOTAL_LEDS;i++){
if(currentTime>times_off[i]){ //текуще время больше, расчетного "времени включения"
digitalWrite(LED_PINS[i],HIGH); //включаем
if(times_off[i]){ //отчитываемся в serial только если диод был выключен
Serial.print(millis());
Serial.print(":TurnOff");Serial.println(i);
}
times_off[i]=0;// помечаем что диод горит
}
}
}
Подскажите , как реализовать защиту от повторного нажатия кнопки в течении ,допустим, 5-ти секунд и осуществить обратную связь между загоранием светофоров и судьей(допустим, при зажигании светофора рукоятка с кнопкой в руке судьи кратковременно вибрирует.Микровибромоторы я нашел).
Вот что получилось...
byte LED_PINS[]={13,12,11}; // номера пинов светодиодов, настройте в соотвествии с вашими подключениями
#define TOTAL_LEDS sizeof(LED_PINS)/sizeof(byte)
unsigned long times_off[TOTAL_LEDS];// тут будем хранить время, когда диоды нужно выключить
int buttonIndex;
void setup(){
Serial.begin(9600);
for(byte i=0;i<TOTAL_LEDS;i++){
pinMode(LED_PINS[i],OUTPUT);// настроиваем порты
times_off[i]=0; //по умолчанию все диоды включены
digitalWrite(LED_PINS[i],HIGH);
}
Serial.println("Ready for command");
}
void loop(){
if(Serial.available()){
buttonIndex = Serial.read()-48;
buttonIndex=buttonIndex-1; // в массиве нумерация идет с нуля
Serial.print(millis());
Serial.print(":Readed buttonIndex=");Serial.println(buttonIndex);
if(buttonIndex>=0 && buttonIndex<TOTAL_LEDS){ //игнорируем случайный мусор, если вдруг прийдет
if(!times_off[buttonIndex]){ // если диод уже выключен - игнорируем повторное нажатие кнопки. Выключаем только включенные
digitalWrite(LED_PINS[buttonIndex],LOW); //выключаем
Serial.print(millis());
Serial.print(":TurnOn");Serial.println(buttonIndex);
times_off[buttonIndex]=millis()+2000;// запоминаем время когда нужно будет включить
}
}
}
//проверяем, не настало-ли время включать
unsigned long currentTime=millis();
for(byte i=0;i<TOTAL_LEDS;i++){
if(currentTime>times_off[i]){ //текуще время больше, расчетного "времени включения"
digitalWrite(LED_PINS[i],HIGH); //включаем
if(times_off[i]){ //отчитываемся в serial только если диод был выключен
Serial.print(millis());
Serial.print(":TurnOff");Serial.println(i);
}
times_off[i]=0;// помечаем что диод горит
}
}
}
byte LED_PINS[]={13,12,11}; // номера пинов светодиодов, настройте в соотвествии с вашими подключениями
#define TOTAL_LEDS sizeof(LED_PINS)/sizeof(byte)
unsigned long times_off[TOTAL_LEDS];// тут будем хранить время, когда диоды нужно выключить
int buttonIndex;
void setup(){
Serial.begin(9600);
for(byte i=0;i<TOTAL_LEDS;i++){
pinMode(LED_PINS[i],OUTPUT);// настроиваем порты
times_off[i]=0; //по умолчанию все диоды включены
digitalWrite(LED_PINS[i],HIGH);
}
Serial.println("Ready for command");
}
void loop(){
if(Serial.available()){
buttonIndex = Serial.read()-48;
buttonIndex=buttonIndex-1; // в массиве нумерация идет с нуля
Serial.print(millis());
Serial.print(":Readed buttonIndex=");Serial.println(buttonIndex);
if(buttonIndex>=0 && buttonIndex<TOTAL_LEDS){ //игнорируем случайный мусор, если вдруг прийдет
if(!times_off[buttonIndex]){ // если диод уже выключен - игнорируем повторное нажатие кнопки. Выключаем только включенные
digitalWrite(LED_PINS[buttonIndex],LOW); //выключаем
Serial.print(millis());
Serial.print(":TurnOn");Serial.println(buttonIndex);
times_off[buttonIndex]=millis()+2000;// запоминаем время когда нужно будет включить
}
}
}
//проверяем, не настало-ли время включать
unsigned long currentTime=millis();
for(byte i=0;i<TOTAL_LEDS;i++){
if(currentTime>times_off[i]){ //текуще время больше, расчетного "времени включения"
digitalWrite(LED_PINS[i],HIGH); //включаем
if(times_off[i]){ //отчитываемся в serial только если диод был выключен
Serial.print(millis());
Serial.print(":TurnOff");Serial.println(i);
}
times_off[i]=0;// помечаем что диод горит
}
}
}
Вопросы те-же...Подскажите , как реализовать защиту от повторного нажатия кнопки в течении ,допустим, 5-ти секунд и осуществить обратную связь между загоранием светофоров и судьей(допустим, при зажигании светофора рукоятка с кнопкой в руке судьи кратковременно вибрирует.Микровибромоторы я нашел).
Вопросы те-же...Подскажите , как реализовать защиту от повторного нажатия кнопки в течении ,допустим, 5-ти секунд и осуществить обратную связь между загоранием светофоров и судьей(допустим, при зажигании светофора рукоятка с кнопкой в руке судьи кратковременно вибрирует.Микровибромоторы я нашел).
1. Строчки 44-61 (ну или 41-58) - до этих блоков явно что-то должно стоять еще. Ибо открывающих фигурных скобок две, а закрывающих аж 4.
2. Делайте отступы в теле скетча - очень трудно уследить, где начинается логический блок, и где он кончается.
По поводу предотвращения нажатий - у вас уже есть массив times_off. Насколько я понимаю, он используется для выключения светодиодов через определенное время после старта. И в него записываются моменты нажатия соответствующих кнопок.
Сделайте так:
перед записью момента нажатия кнопки сравнивайте текущее значение часов с записанным в соответствующую ячейку массива. Если разница больше ваших 5 секунд ("if(millis()-times_off[buttonIndex]>3000) { // учитывая, что в массив вы загнали время отключения диода, т.е. время нажатия+2000") - действуйте как и раньше: записывайте в массив время нажатия кнопки, включайте светодиоды, ...
Если разница меньше 5 секунд - ничего не делайте (и особенно - НЕ ЗАПИСЫВАЙТЕ В МАССИВ ВРЕМЯ НАЖАТИЯ КНОПКИ). Или все-же делайте. Например, мигайте на клавиатуре каким-нибудь "аварийным" диодиком, призывая нажимающего поиметь немного терпения.
Ах, да... Сейчас вы обнуляете элемент массива после тушения светодиода. Т.е. через две секунды нужное нам значение времени исчезает. Следует:
1) либо переписать логику в программе, используя вместо if(times_off[buttonIndex]) условие вроде if(millis()-times_off[buttonIndex]>=0) (и не обнуляя значения эл-тов массива после гашения соотв диода)
2) либо ввести еще один массив, подобный times_off и используемый по той же логике, но настраиваемый не на 2, а на 5 секунд.
Поскольку у вас логика достаточно сильно завязана на проверке нулевых значений, первый путь может оказаться достаточно трудоемким и чреватым срывом логики в условиях отсутствия наличия опыта в программировании. Для второго придется лишь парой десятков байтов RAM пожертвовать.
В общем-то и все. Через две секунды после "правильного" нажатия кнопки вы сможете загасить свои светодиоды. Через пять секунд - вышеописанное условие перестанет блокировать нажатие кнопки.
>Строчки 44-61 (ну или 41-58) - до этих блоков явно что-то должно стоять еще.
Не должно. Все компилится.
........
>Сделайте так:
Хоть изначально я писал этот код. Но сам с трудом понял эти советы. Сам предполагал именно "либо ввести еще один массив, подобный times_off и используемый по той же логике". Зачем трогать логику светодиодов которая работает? Просто раньше было что "задержка от повтора" равнялось "времени горения", вот и не заводилась отдельная переменная, если нужто что-бы "отличалась" - заведем ;)
Это наиболее близко к тому что я говорил отдавая скетч "дальше - по аналогии" :)
2 R164
Осталось только уточнить маленькую деталь. Эта общая для все кнопок или независимая. То есть если я нажал первую кнопку, то в течении пяти секунд игнорятся все кнопки или только первая?
Вот, пока логику не менял, просто причесал/отформатировал
#define LED_DELAY 2000 // время горения светодиода
byte LED_PINS[]={13,12,11}; // номера пинов светодиодов, настройте в соотвествии с вашими подключениями
#define TOTAL_LEDS sizeof(LED_PINS)/sizeof(byte)
unsigned long times_off[TOTAL_LEDS];// тут будем хранить время, когда диоды нужно выключить
int buttonIndex;
void setup(){
Serial.begin(9600);
for(byte i=0;i<TOTAL_LEDS;i++){
pinMode(LED_PINS[i],OUTPUT);// настроиваем порты
times_off[i]=0; //по умолчанию все диоды выключены
digitalWrite(LED_PINS[i],HIGH);
}
Serial.println("Ready for command");
}
void loop(){
if(Serial.available()){
buttonIndex = Serial.read()-48;
buttonIndex=buttonIndex-1; // в массиве нумерация идет с нуля
Serial.print(millis());
Serial.print(":Readed buttonIndex=");Serial.println(buttonIndex);
if(buttonIndex>=0 && buttonIndex<TOTAL_LEDS){ //игнорируем случайный мусор, если вдруг прийдет
if(!times_off[buttonIndex]){ // если диод уже включен - игнорируем повторное нажатие кнопки. Включаем только выключенные
digitalWrite(LED_PINS[buttonIndex],LOW); //включаем
Serial.print(millis());
Serial.print(":TurnOn");Serial.println(buttonIndex);
times_off[buttonIndex]=millis()+LED_DELAY;// запоминаем время когда нужно будет выключить
}
}
}
//проверяем, не настало-ли время включать
unsigned long currentTime=millis();
for(byte i=0;i<TOTAL_LEDS;i++){
if(currentTime>times_off[i]){ //текуще время больше, расчетного "времени выключения"
digitalWrite(LED_PINS[i],HIGH); //выключаем
if(times_off[i]){ //отчитываемся в serial только если диод был включен
Serial.print(millis());
Serial.print(":TurnOff");Serial.println(i);
}
times_off[i]=0;// помечаем что диод горит
}
}
}
Вот каждая кнопка блокируется на 5-ть сек независимо. Жирные строчки которые меняют логику (остальные изменения - косметика).
#define LED_DELAY 2000 // время горения светодиода
#define IGNORE_BUTTON_TIME 5000 // время, сколько нужно игнорировать кнопку
byte LED_PINS[]={13,12,11}; // номера пинов светодиодов, настройте в соотвествии с вашими подключениями
#define TOTAL_LEDS sizeof(LED_PINS)/sizeof(byte)
unsigned long times_off[TOTAL_LEDS];// тут будем хранить время, когда диоды нужно выключить
unsigned long times_enable_buttons[TOTAL_LEDS]; // тут будем хранить время, когда на кнопку "можно реагировать".
int buttonIndex;
void setup(){
Serial.begin(9600);
for(byte i=0;i<TOTAL_LEDS;i++){
pinMode(LED_PINS[i],OUTPUT);// настроиваем порты
times_off[i]=0; //по умолчанию все диоды выключены
digitalWrite(LED_PINS[i],HIGH);
times_enable_buttons[i]=0; // по умолчанию все кнопки разрешены
}
Serial.println("Ready for command");
}
void loop(){
unsigned long currentTime=millis();
if(Serial.available()){
buttonIndex = Serial.read()-48;
buttonIndex=buttonIndex-1; // в массиве нумерация идет с нуля
Serial.print(millis());
Serial.print(":Readed buttonIndex=");Serial.println(buttonIndex);
if(buttonIndex>=0 && buttonIndex<TOTAL_LEDS){ //игнорируем случайный мусор, если вдруг прийдет
if(times_enable_buttons[buttonIndex] < currentTime){ // игнорируем если еще не настало время, когда на кнопку можно смотреть
digitalWrite(LED_PINS[buttonIndex],LOW); //включаем
Serial.print(currentTime);
Serial.print(":TurnOn");Serial.println(buttonIndex);
times_off[buttonIndex]=currentTime+LED_DELAY;// запоминаем время когда нужно будет выключить
times_enable_buttons[buttonIndex]=currentTime+IGNORE_BUTTON_TIME; // запоминаем время когда опять можно нажимать на кнопку
}
}
}
//проверяем, не настало-ли время включать
for(byte i=0;i<TOTAL_LEDS;i++){
if(currentTime>times_off[i]){ //текуще время больше, расчетного "времени выключения"
digitalWrite(LED_PINS[i],HIGH); //выключаем
if(times_off[i]){ //отчитываемся в serial только если диод был включен
Serial.print(millis());
Serial.print(":TurnOff");Serial.println(i);
}
times_off[i]=0;// помечаем что диод горит
}
}
}
Но, если честно не проверял. Так что потестите уже сами.
А на передающей, для вжиков, тоже должна быть задерка от повторного нажатия? Или сколько раз нажал, столько раз и вжикнуло? А если "нажал и держиш", должно "жужать" или только в момент нажатия?
А на передающей, для вжиков, тоже должна быть задерка от повторного нажатия? Или сколько раз нажал, столько раз и вжикнуло? А если "нажал и держиш", должно "жужать" или только в момент нажатия?
Вжики я придумал только для того, чтобы судья был уверен, что его нажатие произвело какое-то действие в системе, или подтверждение нажатия для самого нажимающего на кнопку судьи. Такая вот обратная связь.Поэтому, мне кажется, :
1.задержки делать не надо
2. сколько раз нажал,столько и вжикнуло
3."нажал и держишь"-пусть жужжит,пока держит, быстрее отпустит...
Тогда непонятно почему у самого не получилось... фактически же вообще логики нет. Дописать только включение/выключение
byte BUTTON_PINS[]={3,4,5}; // номера пинов конопок, настройте в соотвествии с вашими подключениями
#define TOTAL_BUTTONS sizeof(BUTTON_PINS)/sizeof(byte)
byte MOTOR_PINS[]={6,7,8};// номера пинов на который подключены моторы, поменяйте как удобней подключать
void setup(){
for(byte i=0;i<TOTAL_BUTTONS;i++){
pinMode(BUTTON_PINS[i],INPUT);
pinMode(BUTTON_PINS[i],HIGH); //включаем подтягивающие резисторы
pinMode(MOTOR_PINS[i],OUTPUT); // настраиваем пины для моторов на выход
}
Serial.begin(9600);
}
void loop(){
for(byte i=0;i<TOTAL_BUTTONS;i++){ //опрашиваем кнопки
if(!digitalRead(BUTTON_PINS[i])){ // если кнопка нажата
Serial.print(i+1); // посылаем ее индекс. в нумерации "от единицы".
digitalWrite(MOTOR_PINS[i],HIGH);//включили мотор
} else digitalWrite(MOTOR_PINS[i],LOW);//выключили мотор
}
}
Только не забудте, что если моторы питать от пинов подключать можно только если они жрут не более 40ma. Иначе нужно через какой-нибудь транзистор, ULN2003 и т.п. Вообщем через какой-нибудь усилитель тока.
Тогда непонятно почему у самого не получилось... фактически же вообще логики нет. Дописать только включение/выключение
Представьте ситуацию.Судья жмет кнопку на отправляющей дуине , получает подтверждающий вжик от нее, но светофор не загорается(проблемы принимающей стороны).Как завязать логически факт загорания светофора и вжика на судейской кнопке? То есть,чтобы только после загорания светофора судья получал подтверждающий вжик на свою кнопку . Радиообмен ведь двухсторонний..
Тю... ну скрестить принимающую и отдающую логику :)
Что-бы не взрывать мозг, раз они обе будут "передавать/принимать",на сменим терминологию с "передающий/принимающей" на "кнопочная/сфетофорная".
В светофорную, добавить аналогично кнопочной, только говорить не "у нас нажата кнопка", а "мы зажгли светофор",
а в кнопочную, наоборот, взять логику из светофорной. Только зажигание сфетофоров, заменяем на включение моторов :)
То есть в итоге, обе должны и принимать и передавать.
Попробуйте разобратся с теми скетчами что есть.... (5-ть секунд игнора заработало или нет?) в них самих уже есть "примеры". Как посылать, и как "передавать". Единственно что в сфетофорной, прийдется выкинуть/закоментировать отладочные serial.print, что-бы они не сбивали кнопочную с толку.
Не получится - попозже накидаю, но наверное, не сегодня.
byte BUTTON_PINS[]={3,4,5}; // номера пинов конопок, настройте в соотвествии с вашими подключениями
#define MOTOR_TIME 300 // время "вжика" мотора в миллисекундах
#define MARKER_TIMEOUT 200 // время в миллисекундах, сколько мы можем ждать индекса после маркера. Если за это время индекс не пришел - забываем про маркер
unsigned long markerTime=0;// время когда мы "поймали" маркер светофора
#define TOTAL_BUTTONS sizeof(BUTTON_PINS)/sizeof(byte)
byte MOTOR_PINS[]={6,7,8};// номера пинов на который подключены моторы, поменяйте как удобней подключать
unsigned long times_off[TOTAL_BUTTONS];// тут будем хранить время, когда моторы нужно выключить
void setup(){
for(byte i=0;i<TOTAL_BUTTONS;i++){
pinMode(BUTTON_PINS[i],INPUT);
pinMode(BUTTON_PINS[i],HIGH); //включаем подтягивающие резисторы
pinMode(MOTOR_PINS[i],OUTPUT); // настраиваем пины для моторов на выход
}
Serial.begin(9600);
}
void loop(){
buttonsMon(); // смотрим на кнопки
serialMon(); // смотрим в Serial
offMotors(); // смотрим время и выключаем, если нужно, мооторы
}
// проверяем все кнопки, и сообщаем в Serial о нажатии
void buttonsMon(){
for(byte i=0;i<TOTAL_BUTTONS;i++){ //опрашиваем кнопки
if(!digitalRead(BUTTON_PINS[i])){ // если кнопка нажата
Serial.print(i+1); // посылаем ее индекс. в нумерации "от единицы".
}
}
}
// наблюдает за Serial, вылавливает в нем сообщения о включении светофора
void serialMon(){
if(Serial.available ()){ //пришли какие-то данные
byte ch=Serial.read();
if(ch=='*') { // это маркер
markerTime=millis();// запомнили когда мы его поймали
}
if(millis()-markerTime>MARKER_TIMEOUT)markerTime=0;// забываем про маркер, время вышло
if(markerTime && ch!='*'){ // что-то поймали после маркера
// пытаемся это интерпретировать как индекс светофора
int buttonIndex = ch-48;
buttonIndex=buttonIndex-1; // в массиве нумерация идет с нуля
if(buttonIndex>=0 && buttonIndex<TOTAL_BUTTONS){ //игнорируем случайный мусор, если вдруг прийдет
markerTime=0;// "сбросили" флаг маркера, больше не ждем индекс
if(!times_off[buttonIndex]){ // включаем только выключеные моторы
digitalWrite(MOTOR_PINS[buttonIndex],HIGH); // влючили мотор
times_off[buttonIndex]=millis()+MOTOR_TIME;// высчитали время когда его нужно будет выключить
}
}
}
}
}
// проверяем все моторы и выключает если "время пришло"
void offMotors(){
unsigned long currentTime=millis();
for(byte i=0;i<TOTAL_BUTTONS;i++){
if(times_off[i]>currentTime){ //пора выключать
digitalWrite(MOTOR_PINS[i],LOW); // выключили мотор
times_off[i]=0; // пометили что выключили
}
}
}
Cветофорный скетч:
#define LED_DELAY 2000 // время горения светодиода
#define IGNORE_BUTTON_TIME 5000 // время, сколько нужно игнорировать кнопку
byte LED_PINS[]={13,12,11}; // номера пинов светодиодов, настройте в соотвествии с вашими подключениями
#define TOTAL_LEDS sizeof(LED_PINS)/sizeof(byte)
unsigned long times_off[TOTAL_LEDS];// тут будем хранить время, когда диоды нужно выключить
unsigned long times_enable_buttons[TOTAL_LEDS]; // тут будем хранить время, когда на кнопку "можно реагировать".
int buttonIndex;
void setup(){
Serial.begin(9600);
for(byte i=0;i<TOTAL_LEDS;i++){
pinMode(LED_PINS[i],OUTPUT);// настроиваем порты
times_off[i]=0; //по умолчанию все диоды выключены
digitalWrite(LED_PINS[i],HIGH);
times_enable_buttons[i]=0; // по умолчанию все кнопки разрешены
}
Serial.println("Ready for command");
}
void loop(){
unsigned long currentTime=millis();
if(Serial.available()){
buttonIndex = Serial.read()-48;
buttonIndex=buttonIndex-1; // в массиве нумерация идет с нуля
Serial.print(millis());
Serial.print(":Readed buttonIndex=");Serial.println(buttonIndex);
if(buttonIndex>=0 && buttonIndex<TOTAL_LEDS){ //игнорируем случайный мусор, если вдруг прийдет
if(times_enable_buttons[buttonIndex] < currentTime){ // игнорируем если еще не настало время, когда на кнопку можно смотреть
digitalWrite(LED_PINS[buttonIndex],LOW); //включаем
Serial.print(currentTime);
Serial.print(":");
for(byte k=0;k<3;k++){ // на всякий случай, вдруг связь плохая, посылаем сообщение о включении светофора три раза
Serial.print("*");// посылаем маркер, что-бы "кнопочная" могла отличить данные от отладочной инфы
Serial.print(buttonIndex+1);// посылаем номер сфетофора в "человеческой" индексации.
}
Serial.println();
times_off[buttonIndex]=currentTime+LED_DELAY;// запоминаем время когда нужно будет выключить
times_enable_buttons[buttonIndex]=currentTime+IGNORE_BUTTON_TIME; // запоминаем время когда опять можно нажимать на кнопку
}
}
}
//проверяем, не настало-ли время включать
for(byte i=0;i<TOTAL_LEDS;i++){
if(currentTime>times_off[i]){ //текуще время больше, расчетного "времени выключения"
digitalWrite(LED_PINS[i],HIGH); //выключаем
if(times_off[i]){ //отчитываемся в serial только если диод был включен
Serial.print(millis());
Serial.print(":TurnOff");Serial.println(i);
}
times_off[i]=0;// помечаем что диод горит
}
}
}
Спасибо огромное,вылез косяк по железу принимаюшей стороны.Дуина ФИО работает от 3 вольт, релейный блок- от 5.Поднимаю напругу на реле до 5 в, дуина перестает работать,реле постоянно включенно.Все перепробовал,бесполезно.Выкрутился, взял одну банку LiPo с 3-х омной нагрузкой--все заработало, сейчас тестирую.Оказалось ,ФИО выше 4 воль не работает.
Ready for command
7806:Readed buttonIndex=0
7809:TurnOn0
7811:Readed buttonIndex=-39
9814:TurnOff0
В скайпе бываю редко.Сейчас попробую наладить....
.
Хм.. по этому логу происходит ровно одно включение 13-того пина, и ровно одно выключение.
Я вижу три варианта:
И кстати, я практически уверен что это лог когда вы нажатия отправляете не с другой дуины, а руками в Serial. Зачем мне лог ситуации когда "все работает правильно" (по вашим словам)? Мне нужен лог ситуации когда проблема есть в наличии. То ест когда "шлет другая". Когда проявляется "лишние включение".
P.S. В скайпе отправил вам запрос на авторизацию еще вчера, но пока вас не вижу Online.
Абсолютно правы.Я неправильно понял ваше"А что при этом видно в Serial Monitor у "принимающей"?"Прицепил принимающую дуину к сериал-монитору и руками подавал команды .В скетч не лазил, упаси Бог !
Поскольку порты у дуин заняты р/модулями, решил еще один модуль на той-же частоте повесить на сериал-монитор. И повключал первую кнопку. И..ни хрена не понял :все прекрасно один раз включается,горит 2 сек, выключается .Чудеса какие-то..Может, по ночам меньше сидеть надо? Но точно -же было,считал промежутки секундомером...
На сериал-мониторе :
1130930:Readed byttoIndex=0
130932:TurnOn0
11131100:Readed byttoIndex=0
131104:Readed byttoIndex=0
132935:TurnOff0
причем почему-то то два раза подряд пишет "11131100:Readed byttoIndex=0
131104:Readed byttoIndex=0,
то один раз.Светодиод загорается исправно в любом случае..
Вроде скайп наладил. Посмотрите пожалуйста
Отправил вам повторый запрос на скайп имя r164r164. Но не вижу вас Online.Вначале вы должны подтвердить мой запрос.
Может вы на другое имя "наладили" скайп?
На всякий случай отправил вам свой скайп на почту. Попробуйте, может у вас получится достучатся до меня.
Спасибо,так действительно лучше.Сейчас попробую. Смущает только,что при последовательном соединении выход из строя светодиода нарушит работу модуля? Или это невероятно с их ресурсом?
На почте у меня пусто.Скайп включен, имя правильное...
>В скетч не лазил, упаси Бог !
Зачем же так? Если это ваше хобби, и вы хотите чему-то учится. Иметь возможность самому что-то делать - лазить в скетч НУЖНО. Эксперементировать, смотреть что получается (ну естественно после того как заработало минимальное). Как дети учатся. Берут и пробуют :)
>Поскольку порты у дуин заняты р/модулями, решил еще один модуль на той-же частоте повесить на сериал-монитор.
Честно говоря - ничего не понял. Я имел ввиду такое подключение: дуины соединяем крест-накрест, к принимающий подтыкиваем USB кабель, и на компе открываем Serial Monitor.
>причем почему-то то два раза подряд пишет "11131100:Readed byttoIndex=0
Эта надпись означает "что-то пришло от передающей", а та может и 10-ть раз слать. В зависимости от того сколько времени держите кнопку. Если вы не убирали delay(500), то будет слать каждые пол секунды (если кнопка нажата). Если убрать delay (или уменьшить) - гораздо чаще. У брать его будет нужно (если у вас скорости 300-400км/ч то эта пол.секундная задержка может играть рояль). И скорость порта, возможно, нужно будет поднять повыше чем 9600 (но это уже от ваших передатчиков зависит, на какой скорости они стабильно работают).
Но так как у нас есть проверка "игнорировать пока горит диод" - это ничему не мешает. Разве что эфир "забивается". Если это критично, то можно, на передающей, запоминать предыдущие состояния кнопок, и отсылать номер, только если "состояние изменилось". А не "пока держим".
>На почте у меня пусто
Может в папку спам попало? (хотя никогда такого с моей почтой небыло).
>Скайп включен, имя правильное...
Посмотрите в скайпе вкладку "последние" (с часиками такая), может вы проморгали мои запросы авторизации.
Если "нет", то... не судьба. Светить свои контакты публично - я не буду.
По поводу радио-модулей и скорости
Если верить http://wiki.openpilot.org/display/Doc/APC220+Transceiver+Telemetry
То между собой они могут общатся масимум, на скорости 19200. Но зависит от растояния. Производитель обещает 9600 на растоянии 1.2км.
С самой ардуиной они могут общатся "побыстрее". До 57600.
Необходимости что-бы скосрости связи ардуино<->модуль и модуль<->модуль точно совпадали - скорее всего нет. Даже лучше будет если ардуино<->модуль будет на более высокой скорости чем модуль<->модуль.
Поэтому в скетчах я бы ставил скорость 28800 или 38400 (что-бы был запас). А сами модули соединял на 19200 и ниже (опытно подбирая на какой скорости они стабильно держут связь).
Ваши скетчи работают прекрасно, спасибо огромное. ПрименяемыЙ мной релейныЙ блок :http://www.ebay.com/itm/Four-4-Channel-5V-Relay-Module-Expansion-Board-Arduino-PIC-AVR-ARM-MCU-DSP-/160750012993?pt=LH_DefaultDomain_0&hash=item256d728a41
потребление на одну релюшку -70-80 мА
сама дуина с р/модулем ест немного :около 20 мА(9, высший уровень мощности р/модуля)
У вас и так стоят транзисторы на релейном блоке. Рядом с разЪемом 4 резистора на 1 кОм, даже при коротком замыкании транзистора при 5 вольтах на пине максимальный ток составит 5 мА. Вы как ток мериете? Случайно не между пином и землей?
На резюках- 102
На резюках- 102
Все правильно 1 кОм, я схему нашел.
"Вы как ток мериете? Случайно не между пином и землей?"
В разрыв плюса питания вставляю амперметр, измеряю потребление ардуины с модулем,затем подаю кнопкой сигнал на одну ногу, опять меряю , отнимаю одно от другого.Неправильно ?
Таким образом вы измеряете потребляемый ток дуины и самих реле, а не ток на ноге. Если хотите можете ради эксперемента померить ток на ноге, подключив амперметр в разрыв между пином и блоком реле, но уверяю вас ток будет маленьким. И если бы на ногах дуины были действительно такие токи, то МК сильно грелся и в итоге сгорел бы.
Ага,понял,спасибо.Но почему релюшки не работают ?Может, питание реле взять отдельно с аккамулятора, а
В смысле при 5 вольтах? Вы питание релейного блока откуда берете?
Кажется,понял.Брал с 3V3 и GND дуины. А надо было с акка ...пойду попробую
Лучше с 5V и GND, но при этом нужно проверить как сильно греется стабилизатор на дуине при всех сработавших реле. А напряжение на аккуме какое?
LiFe , 3.3 вольта .Все работает прекрасно.Реле запитал прямо от него , упр. сигналы -с ног.Приношу свои извинения.Неправильный коммент удалил...
СПАСИБО
Не хочу искать выше, поэтому спрошу - а чем вы этими реле хотите управлять?
3-х цветный Светодиодный светофор на акках.
А потребляемый ток "одного цвета" известен?
3-5 ампер, максимум
Да, большой емкости должны быть аккумуляторы, что бы работать на таких токах. В ощем при 3 амперах можно использовать обычные транзисторы, но прикрученных к радиатору. Но т.к. у вас уже есть блок реле, то пусть он и будет.
Время горения каждого цвета - около 30 сек за 1 гонку.Гонок в день-10-15 в лучшем случае.Думаю, немного.
Честно говоря ,сам хотел транзисторную сборку,нет контактов, быстрей, надежней.Но готовую не нашел, а тратить время на это нет смысла, пока не решены самые сложные для меня програмные проблемы комплекса...
Так вроде вы тут программные вопросы все решили...
Это не я решил. Это программер и просто хороший человек под ником "leshak " решил все мои програмные проблемы, связанные с беспроводным управлением светофором, являюшимся частью судейского комплекса,за что ему огромное спасибо от меня и других спортсменов -авиамоделистов .Теперь на базе его решения по аналогии(по другому пока не умею) буду городить весь судейский комплекс ,результаты-сюда. Буду рад любой помощи.Михаил
Извиняюсь за молчание, двое стартов подряд.
Итак, крайний работающий скетч(автор"leshak ") с инвертированным сигналом пинов13,12,11 принимающей дуины для управления сигнальным нолем релейного блока трехцветного светофора:
byte LED_PINS[]={13,12,11}; // номера пинов светодиодов, настройте в соотвествии с вашими подключениями
#define TOTAL_LEDS sizeof(LED_PINS)/sizeof(byte)
unsigned long times_off[TOTAL_LEDS];// тут будем хранить время, когда диоды нужно выключить
int buttonIndex;
void setup(){
Serial.begin(9600);
for(byte i=0;i<TOTAL_LEDS;i++){
pinMode(LED_PINS[i],OUTPUT);// настроиваем порты
times_off[i]=0; //по умолчанию все диоды включены
digitalWrite(LED_PINS[i],HIGH);
}
Serial.println("Ready for command");
}
void loop(){
if(Serial.available()){
buttonIndex = Serial.read()-48;
buttonIndex=buttonIndex-1; // в массиве нумерация идет с нуля
Serial.print(millis());
Serial.print(":Readed buttonIndex=");Serial.println(buttonIndex);
if(buttonIndex>=0 && buttonIndex<TOTAL_LEDS){ //игнорируем случайный мусор, если вдруг прийдет
if(!times_off[buttonIndex]){ // если диод уже выключен - игнорируем повторное нажатие кнопки. Выключаем только включенные
digitalWrite(LED_PINS[buttonIndex],LOW); //выключаем
Serial.print(millis());
Serial.print(":TurnOn");Serial.println(buttonIndex);
times_off[buttonIndex]=millis()+2000;// запоминаем время когда нужно будет включить
}
}
}
//проверяем, не настало-ли время включать
unsigned long currentTime=millis();
for(byte i=0;i<TOTAL_LEDS;i++){
if(currentTime>times_off[i]){ //текуще время больше, расчетного "времени включения"
digitalWrite(LED_PINS[i],HIGH); //включаем
if(times_off[i]){ //отчитываемся в serial только если диод был выключен
Serial.print(millis());
Serial.print(":TurnOff");Serial.println(i);
}
times_off[i]=0;// помечаем что диод горит
}
}
}
Подскажите , как реализовать защиту от повторного нажатия кнопки в течении ,допустим, 5-ти секунд и осуществить обратную связь между загоранием светофоров и судьей(допустим, при зажигании светофора рукоятка с кнопкой в руке судьи кратковременно вибрирует.Микровибромоторы я нашел).
http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
Вопросы те-же...Подскажите , как реализовать защиту от повторного нажатия кнопки в течении ,допустим, 5-ти секунд и осуществить обратную связь между загоранием светофоров и судьей(допустим, при зажигании светофора рукоятка с кнопкой в руке судьи кратковременно вибрирует.Микровибромоторы я нашел).
1. Строчки 44-61 (ну или 41-58) - до этих блоков явно что-то должно стоять еще. Ибо открывающих фигурных скобок две, а закрывающих аж 4.
2. Делайте отступы в теле скетча - очень трудно уследить, где начинается логический блок, и где он кончается.
По поводу предотвращения нажатий - у вас уже есть массив times_off. Насколько я понимаю, он используется для выключения светодиодов через определенное время после старта. И в него записываются моменты нажатия соответствующих кнопок.
Сделайте так:
перед записью момента нажатия кнопки сравнивайте текущее значение часов с записанным в соответствующую ячейку массива. Если разница больше ваших 5 секунд ("if(millis()-times_off[buttonIndex]>3000) { // учитывая, что в массив вы загнали время отключения диода, т.е. время нажатия+2000") - действуйте как и раньше: записывайте в массив время нажатия кнопки, включайте светодиоды, ...
Если разница меньше 5 секунд - ничего не делайте (и особенно - НЕ ЗАПИСЫВАЙТЕ В МАССИВ ВРЕМЯ НАЖАТИЯ КНОПКИ). Или все-же делайте. Например, мигайте на клавиатуре каким-нибудь "аварийным" диодиком, призывая нажимающего поиметь немного терпения.
Ах, да... Сейчас вы обнуляете элемент массива после тушения светодиода. Т.е. через две секунды нужное нам значение времени исчезает. Следует:
1) либо переписать логику в программе, используя вместо if(times_off[buttonIndex]) условие вроде if(millis()-times_off[buttonIndex]>=0) (и не обнуляя значения эл-тов массива после гашения соотв диода)
2) либо ввести еще один массив, подобный times_off и используемый по той же логике, но настраиваемый не на 2, а на 5 секунд.
Поскольку у вас логика достаточно сильно завязана на проверке нулевых значений, первый путь может оказаться достаточно трудоемким и чреватым срывом логики в условиях отсутствия наличия опыта в программировании. Для второго придется лишь парой десятков байтов RAM пожертвовать.
В общем-то и все. Через две секунды после "правильного" нажатия кнопки вы сможете загасить свои светодиоды. Через пять секунд - вышеописанное условие перестанет блокировать нажатие кнопки.
>Строчки 44-61 (ну или 41-58) - до этих блоков явно что-то должно стоять еще.
Не должно. Все компилится.
........
>Сделайте так:
Хоть изначально я писал этот код. Но сам с трудом понял эти советы. Сам предполагал именно "либо ввести еще один массив, подобный times_off и используемый по той же логике". Зачем трогать логику светодиодов которая работает? Просто раньше было что "задержка от повтора" равнялось "времени горения", вот и не заводилась отдельная переменная, если нужто что-бы "отличалась" - заведем ;)
Это наиболее близко к тому что я говорил отдавая скетч "дальше - по аналогии" :)
2 R164
Осталось только уточнить маленькую деталь. Эта общая для все кнопок или независимая. То есть если я нажал первую кнопку, то в течении пяти секунд игнорятся все кнопки или только первая?
Вот, пока логику не менял, просто причесал/отформатировал
Вот каждая кнопка блокируется на 5-ть сек независимо. Жирные строчки которые меняют логику (остальные изменения - косметика).
Но, если честно не проверял. Так что потестите уже сами.
Да, еще, по поводу короткого "вжика" моторов. А к чему они подключены-то? К передающей дуине, там где кнопка или к принимающей?
Если нажимается первая кнопка, то в течении 5 сек игнорируется только она .Аналогично вторая и третья кнопки.
"Вжики" подключены к передающей дуине, там, где кнопки...
"Но, если честно не проверял. Так что потестите уже сами."
"
..Снимаю шляпу!...Пошел ваять светофор...
А на передающей, для вжиков, тоже должна быть задерка от повторного нажатия? Или сколько раз нажал, столько раз и вжикнуло? А если "нажал и держиш", должно "жужать" или только в момент нажатия?
А на передающей, для вжиков, тоже должна быть задерка от повторного нажатия? Или сколько раз нажал, столько раз и вжикнуло? А если "нажал и держиш", должно "жужать" или только в момент нажатия?
Вжики я придумал только для того, чтобы судья был уверен, что его нажатие произвело какое-то действие в системе, или подтверждение нажатия для самого нажимающего на кнопку судьи. Такая вот обратная связь.Поэтому, мне кажется, :
1.задержки делать не надо
2. сколько раз нажал,столько и вжикнуло
3."нажал и держишь"-пусть жужжит,пока держит, быстрее отпустит...
Тогда непонятно почему у самого не получилось... фактически же вообще логики нет. Дописать только включение/выключение
Только не забудте, что если моторы питать от пинов подключать можно только если они жрут не более 40ma. Иначе нужно через какой-нибудь транзистор, ULN2003 и т.п. Вообщем через какой-нибудь усилитель тока.
Тогда непонятно почему у самого не получилось... фактически же вообще логики нет. Дописать только включение/выключение
Представьте ситуацию.Судья жмет кнопку на отправляющей дуине , получает подтверждающий вжик от нее, но светофор не загорается(проблемы принимающей стороны).Как завязать логически факт загорания светофора и вжика на судейской кнопке? То есть,чтобы только после загорания светофора судья получал подтверждающий вжик на свою кнопку . Радиообмен ведь двухсторонний..
Тю... ну скрестить принимающую и отдающую логику :)
Что-бы не взрывать мозг, раз они обе будут "передавать/принимать",на сменим терминологию с "передающий/принимающей" на "кнопочная/сфетофорная".
В светофорную, добавить аналогично кнопочной, только говорить не "у нас нажата кнопка", а "мы зажгли светофор",
а в кнопочную, наоборот, взять логику из светофорной. Только зажигание сфетофоров, заменяем на включение моторов :)
То есть в итоге, обе должны и принимать и передавать.
Попробуйте разобратся с теми скетчами что есть.... (5-ть секунд игнора заработало или нет?) в них самих уже есть "примеры". Как посылать, и как "передавать". Единственно что в сфетофорной, прийдется выкинуть/закоментировать отладочные serial.print, что-бы они не сбивали кнопочную с толку.
Не получится - попозже накидаю, но наверное, не сегодня.
.... (5-ть секунд игнора заработало или нет?)
Работает, как швейцарские часы, спасибо...
Кнопочный скетч:
Cветофорный скетч:
Спасибо огромное,вылез косяк по железу принимаюшей стороны.Дуина ФИО работает от 3 вольт, релейный блок- от 5.Поднимаю напругу на реле до 5 в, дуина перестает работать,реле постоянно включенно.Все перепробовал,бесполезно.Выкрутился, взял одну банку LiPo с 3-х омной нагрузкой--все заработало, сейчас тестирую.Оказалось ,ФИО выше 4 воль не работает.
Не нравиться акком греть атмосферу...
Диоды Шотке не помогут?
А причем тут диоды? Диоды, это скорее если нужно уровни согласовать. Например у вас приходит управляющий сигнал 5v, а вход может выдержать только 3v.
На питать реле с пина дуины - действительно не самая светаля идея. Почитайте как реле нужно рулить:
http://easyelectronics.ru/upravlenie-moshhnoj-nagruzkoj-postoyannogo-tok...
http://easyelectronics.ru/upravlenie-moshhnoj-nagruzkoj-postoyannogo-tok...
Я бы, пробовал что-то типа ULNxxx/UDNxxx, возможно и релюха тогда не понадобится.
На питать реле с пина дуины - действительно не самая светаля идея. Почитайте как реле нужно рулить:
Спасибо, читал..
С пинов дуины реле вообще не срабатывает.Я запитываю реле прямо с акка...А диды Шотке хотел поставить на сигнальные ноги