Нужна помощь с функцией
- Войдите на сайт для отправки комментариев
Добрый день.
Идея в следующем. Через Serial отправляю номер пина на ардуино, должен загореться диод на этом пине, при повторном - выключится. Тестится все для пина 13. Собственно, не срабатывает ledX=!ledX при вызове функции, т.е. на экране все время "Led 13 is on". Как исправить.
Заранее благодарен))
boolean ledA = LOW;
void switchPin(boolean ledX,int i)
{
if(ledX == LOW)
{
Serial.print("Led ");
Serial.print(i);
Serial.println(" is on");
digitalWrite(i, HIGH);
ledX=!ledX; // не срабатывает
}
else
{
Serial.print("Led ");
Serial.print(i);
Serial.println(" is off");
digitalWrite(i, LOW);
ledX=!ledX;
}
}
void setup() {
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
Serial.begin(9600);
}
void loop() {
while (Serial.available()==0);
int val = Serial.read() - '0';
Serial.println(val);
if(val>9&&val<14) //проверяем число
{
switchPin(ledA,val); //вызываем функцию
}
else
{
Serial.println("Error. Try again");
}
Serial.flush();
}
Строку ledX=!ledX; замените на ledA=!ledA;
Строку ledX=!ledX; замените на ledA=!ledA;
Почему? У него ж ledX - параметр функции, а Вы предлагаете к глобальную переменную менять - некрасиво. Пусть лучше вернёт значение и присвоит его ledA
ммм.. а если я немного переделаю? добавлю еще лампочек? Меня интересует как через функцию меня параметр ledA, так как при каждой отправке на COM порт числа и прокрутке функции, ledA всегда видится как LOW
boolean ledA = LOW;
boolean ledB = LOW;
if(val = 12) //проверяем число
{
switchPin(ledA,val); //вызываем функцию
}
if(val = 13) //проверяем число
{
switchPin(ledB,val); //вызываем функцию
}
sirius1,
во-первых, прежде чем писать на форум, необходимо ознакомиться с его правилами. В частности, прочитайте вот это.
Вот я хочу Вам что-то объяснить, но для объяснений мне нужно ссылаться на номера строк. А где они у Вас? Как мне ссылаться?
Учитывая, что Вы здесь первый день, а я сегодня добрый, я сделаю это за Вас, но впредь так не делайте.
Итак, вот Ваш код.
Всё там у Вас отлично срабатывает, переменная ledX внутри функции меняется. Но Вы, очевидно, ожидаете. что будет заодно меняться и переменная ledA, которая передавалась как параметр. А вот это фигушки! С какого перепугу? Вы ведь её передаёте по значению! Другими словами, Вы передаёте в функцию вычисленное значение переменной ledA а не её саму. Внутри функции Вы можете с этим значением делать что угодно, но снаружи (на самой ledA) это никак не отразится. Что Вы и наблюдаете.
Вариантов как это поправить - 100500.
Самый простой (но далеко не самый лучший) - передавать в функцию не значение ledA, а ссылку на неё. Тогда функция благополучно изменит ledA, т.к. она имеет дело не с вычисленным значением, а со ссылкой на оригинальную переменную. Для того, чтобы ledA передавалась по ссылке достатчно в строке 3 добавить один символ.
и будет Вам счастье. Попробуйте.
Да, и кстати, для чего у Вас делаются одинаковые действия в обеих ветвях if'а? Я имею в виду строки 11 и 19. Незачем дублировать дважды одно и то же. Обе эти строки надо убрать, а вставить одну такую же после строки 20. Будет всё тоже самое, но стилистически правильнее.
Но, как я уже говорил, этот способ не самый лучший. дело в том, что передача по ссылке вообще вещь опасная и противоречащая самой идеологии использования функций (котрая гласит, что функция не должна менять ничего во внешнем мире).
Более идеологочисеки кошерный способ - сделать это через возвращаемое значение.
Для этого
1. В строке 3 заменяем void на boolean (теперь функция будет возвращать значение)
2. Строки 11 и 19 выбрасываем.
3. Между строками 20 и 21 вставляем возврат значения: return ! ledX
4. В строку 37 добавляем приём возвращённого значения. Должно получиться:
И всё должно заработать.
И последнее. Если уж делать совсем по уму, надо перенести строку 1 внутрь функции loop. Нефиг этой переменной быть глобальной - к тому нет никаких причин.
ммм.. а если я немного переделаю? добавлю еще лампочек?
Любым из описанных мною способов будет работать на любое количество лампочек.
Ok. Спасибо больше. Все встало на свои места.
Кстати, по поводу переноса переменной в loop. Не работает)) Может я конечно ее как-то не так переношу, но если оставить ее на строке 1 - все ок
static boolean ledA = LOW;
или boolean ledA ;
Кстати, по поводу переноса переменной в loop. Не работает))
Должно работать. Когда возникают такие вопросы, не ленитесь вставить код. чтобы было видно как именно Вы её перенесли, а то так, вслепую, что можно сказать?
Внутри loop только если static, иначе работать не будет
Собственно вставляю код. С параметром static у переменной все работает... в каких либо других вариантах - нет - ledA всегда в LOW.
а static я так понимаю переменная только внутри функции? т.е. за пределами loop я ее не увижу?
первым оператором цикла, в строке 27, ты присваиваешь ledA LOW, и удивляешься, что она всегда LOW.
Ты странный?
И верно, переменная с модификатором static инициализируется один раз, при первом вызове,, поэтому оно у тебя и работало в таком виде.
оставь так (со "статиком") - сойдет. "Гуру" может и поругают, но работать будет.
В "хорошем" стиле, неважно объектный или процедурный С используем, переменные с текущим состоянием неких предметов (лампочек) - прячем внутрь класса (или функции, тогда они там "static") и наружу оставляем только "хвостки" интерфейсов к ним.
Есть еще подход чисто процедурного С - заводим структуру со всеми признаками и состояниями, и указатель на нее передаем по всем нужным функциям. Так написано 90% ядра Linux. Выбирай сам, если - непонятно - придется курить учебник по программированию.
Ну, разумеется, static.
А снаружи, нет, не увидите. Для того и заносили внутрь.