Помогите новичку дописать код.
- Войдите на сайт для отправки комментариев
 
      Пнд, 12/08/2013 - 00:53
          
      Помогите объеденить и дописать код.
Есть код для включения LED с помощью смс.
и отправка смс с кнопки.
но смс отправляеться только кагда нажать кнопку. а мне надо что бы отправлялось смс и когда отпустить кнопку. т.е. обратная связь для LED. Точнее вместо светодиода будет реле с дублирующими контактами. Надо знать с помощью смс включилось ли реле на самом деле. и оповещать если разомкнулись контакты. Даже если с Ардуины LED (реле) включено.
Код включения LED:
#include <SoftwareSerial.h>
SoftwareSerial gprsSerial(3, 2);
int greenPin = 4;
void setup()
{
    gprsSerial.begin(9600);
    pinMode(greenPin, OUTPUT);
    // Настраиваем приём сообщений с других устройств
    // Между командами даём время на их обработку
    gprsSerial.print("AT+CMGF=1\r");
    delay(300);
    gprsSerial.print("AT+IFC=1, 1\r");
    delay(300);
    gprsSerial.print("AT+CPBS=\"SM\"\r");
    delay(300);
    gprsSerial.print("AT+CNMI=1,2,2,1,0\r");
    delay(500);
}
 
String currStr = "";
// Переменная принимает значение True, если текущая строка является сообщением
boolean isStringMessage = false;
 
void loop()
{
    if (!gprsSerial.available())
        return;
 
    char currSymb = gprsSerial.read();    
    if ('\r' == currSymb) {
        if (isStringMessage) {
            //если текущая строка - SMS-сообщение,
            //отреагируем на него соответствующим образом
            if (!currStr.compareTo("Green on")) {
                digitalWrite(greenPin, HIGH);
            } else if (!currStr.compareTo("Green off")) {
                digitalWrite(greenPin, LOW);
            }
            isStringMessage = false;
        } else {
            if (currStr.startsWith("+CMT")) {
                //если текущая строка начинается с "+CMT",
                //то следующая строка является сообщением
                isStringMessage = true;
            }
        }
        currStr = "";
    } else if ('\n' != currSymb) {
        currStr += String(currSymb);
    }
}
Код отправки смс по нажатию кнопки.
#include <SoftwareSerial.h>
 SoftwareSerial gprsSerial(7, 8);
 int btnPin = 12;
boolean prevBtn = LOW;
 void setup()
{
    gprsSerial.begin(9600);
    delay(500);
}
 void loop()
{
    boolean currBtn = digitalRead(btnPin);
    if (prevBtn != currBtn && currBtn == HIGH) {
        //сразу после нажатия кнопки отправляем "тревожное" сообщение по заданному номеру
        sendTextMessage();
    }
    prevBtn = currBtn;
}
 
/*
 * Функция отправки SMS-сообщения
 */
void sendTextMessage() {
    // Устанавливает текстовый режим для SMS-сообщений
    gprsSerial.print("AT+CMGF=1\r");
    delay(100); // даём время на усваивание команды
    // Устанавливаем адресата: телефонный номер в международном формате
    gprsSerial.println("AT + CMGS = \"+79************\"");
    delay(100);
    // Пишем текст сообщения
    gprsSerial.println("ALARM!");
    delay(100);
    // Отправляем Ctrl+Z, обозначая, что сообщение готово
    gprsSerial.println((char)26);
}
P.S. Прозьба сильно не пинать.. Новичек в этом деле..
          
Для получение развернутого ответа отправьте смс на короткий номер ХХХХХХ
Написать какое железо было видно не сдуьба?
Arduino Diecimila (Atmega168) + ICOMSAT 1.1 (Sim900)
Железо работает. сообщения отправляет при замыкании кнопки. и LEDом управляет при отправке сообщения.
Но я не совсем понимаю как правильно объеденить код.
что бы: отправил смс -> вкл.светодиод. нажал после этого кнопку(и удерживаешь) -> шилд отправил смс что кнопка нажата. Отпустил кнопку -> шилд отправил сообщение что кнопка отпущена. хотя светодиод все равно светиться.
Другими словами, что бы кнопка отправляла смс при нажатии или отпускании и при этом указывалось что произошло: "отпустилась" кнопка или "нажалась".
кнопка и управление светодиодом должны работать независимо.
я так понимаю кнопка должна быть на пине 2 или 3 (апаратное прерывание). и естественно на кнопке физическая защита от дребезга (емкость с резистором).
Так и что именно вас останавливает? полное не понимание кода? Вы ждете что щас все бросятся писать за вас код? Особенно порадовала ЕМКОСТЬ С РЕЗИСТОРОМ .. ух ты прям.. (представил себе такой бидон ( ну емксоть же все таки) и там значит внутри бидона кто то сидит и сопротивляется)
В качестве первого шага попробуйте найти те три строки в ваших кодах, которые отвечают за отправку смс при нажатии кнопки.
Получится - делайте второй шаг: попытайтесь понять, как работает условие, выполнение которого приводит к отправке смс.
Пройдете оба этих шага - останется сущая ерунда: copy+paste+modify.
to, Puhlyavi, я понимаю, что никто не броситься и не напишет за меня код! и таких как я тут полно. но все таки форум не зря открыт. надеялся что хоть ткнете теорией.
по поводу бидона: что Вас так, простите, роздражает, что Вы именно о бидине начали говорить, а не о конденсаторе и резисторе?. почему Jeremy Blum'а никто так не коментировал по поводу емкости? Понятно, что он специалист в этом впросе. Но зачем новичков так "опускать"?
to, Step962: спасибо, попробую - отпишусь.
to, Puhlyavi, я понимаю, что никто не броситься и не напишет за меня код! и таких как я тут полно. но все таки форум не зря открыт. надеялся что хоть ткнете теорией.
Давайте зайдем с начала, что именно вы сделали сами? соединили проводки как на картинке, скопировали 2 скеча с подробными коментариями в один пост... вы не умеете читать коментарии? проблема с понимаем заложеного в коментарии смысла?
Или теория которая вам требуется это список общих функций и примеры их применения?
Что еще я пропустил?
Тут у нас товарищ бегает с примерами на автомобильную тематику...
Так вот ваша ситуация выглядит примерно так.. забегаете в гараж и кричите.. Мужики у меня вот есть двигатель, он рабочий 100 процентов и есть рама от машины, тоже вроде не ржавая.. так эт не заводится нифига, не подскажете почему?
и кто такой Джереми Блум и почему я о нем должен знать? И самое забавное, если вы себе равняете с ним, то почему задаете такие глупые вопросы?
http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-novichku
Меняете "кнопку" на "отправку смс/щелканье релёй" итд
>но смс отправляеться только кагда нажать кнопку. а мне надо что бы отправлялось смс и когда отпустить кнопку. т.е.
Ну вот давайте, тогда, вначале решите эту задачу (и в ее процессе лучше поймете скетч), а потом уже займетесь объединением.
Сможете второй скетч модифицировать таким образом, что-бы он:
1. На нажатие кнопки отсылал SMS "Button Pressed"
2. На отпускание кнопки отсылал SMS "Button Released"
Сможете? Если нет - все равно попробуйте и покажите что получилось :)
ну как то вот так у меня получилось(только вместо отправки мигаю два раза светиками для проверки на железе):
int btnPin = 2; int flag=0; void setup() { pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(2, INPUT); } void loop() { if (digitalRead(2)==HIGH&&flag==0) { Comand_high(); } if (digitalRead(2)==LOW&&flag==1) { Comand_low(); } } void Comand_high() { digitalWrite(7, HIGH); delay(300); digitalWrite(7,LOW); delay(300); digitalWrite(7, HIGH); delay(300); digitalWrite(7, LOW); flag=1; } void Comand_low() { digitalWrite(8, HIGH); delay(300); digitalWrite(8,LOW); delay(300); digitalWrite(8, HIGH); delay(300); digitalWrite(8, LOW); flag=0; }ну как то вот так у меня получилось(только вместо отправки мигаю три раза светиками для проверки на железе):
- Хороший, молодец! ( дал кусочек шоколадки и погладил по голове)
Будем закреплять положительные сдвиги.. но если че у меня тут есть вода в бутылке с разбрызгивателем.
Умеете Вы, Puhlyaviy под...ть...
- Хороший, молодец! ( дал кусочек шоколадки и погладил по голове)
Остроумие - это хорошо. Только применять его нужно к месту и по делу. Иначе остроумие превращается в ослоумие. Человек делом занимается, учится/разбирается. А вы - мешаете.
Это как собака: если лает на цыган лезущих через забор - хорошая охранная собака, если лает на весь белый свет и кусает гостей - это шавка истеричная.
Так что "фу!!!!! молчать!!! на место.."
2Life23: я чуть-чуть позже прокоментирую/поправлю ваш скетч.
Остроумие - это хорошо. Только применять его нужно к месту и по делу. Иначе остроумие превращается в ослоумие. Человек делом занимается, учится/разбирается. А вы - мешаете.
Это как собака: если лает на цыган лезущих через забор - хорошая охранная собака, если лает на весь белый свет и кусает гостей - это шавка истеричная.
Так что "фу!!!!! молчать!!! на место.."
Человек прежде чем начать заниматься делом, попытался внести всем мозг... и только потом решил подзаняться делом...
А на собак вы здря волну гоните, они могут в конце обидется и уйди, оставив вас наедине и с гостями и цыганами и прочим сбродом. Будет вам тогда и тихо, но нервно. Пока у нас как в том старом анекдоте. Помог, чем смог, картошку сажайте сами :) Так что давайте не будем тошнить на нервы друг другу.
Мама пишет в тюрьму сыну:
"Сынок, как тебя посадили, сил нет, некому помогать по хозяйству - огород не вскопанный, картошка не посажена, что делать не знаю!" Сын пишет ответ:
"Мама в огороде не копайся, накопаешь такого, что и тебя посадят и мне срок добавят". Мама опять пишет сыну:
"Сынок, как пришло твое письмо, приехали мусора, перекопали весь огород, ничего не нашли - уехали злые, матерились".
Сын пишет ответ:
"Мама! Чем мог - тем помог, картошку сажайте сами".
да никому я не собирался выносить мозг!!! Вас никто не заставлял отвечать в ветке! если для Вас это тупые вопросы, зачем было отвечать на них? И вообще, мы здравые люди и я думаю эти споры и разборки ни к чему..
ну как то вот так у меня получилось(только вместо отправки мигаю два раза светиками для проверки на железе):
Вообщем, кто бы там чего не зубоскалил, вы конечно молодец, но....
"....оплеухи нужней поцелуев,
поцелуям мы знаем цену..." (с) Дольский
Итак, давайте поищем что можно раскритиковать в вашем скетче :) (и чем его улучшить).
Во первых, в оригинальном скетче переменные работы с кнопками были банально более удачно названы. Тот скетч я смотрел и без всяких подсказок и комментариев мне было понятно, что условие
Означает "изменилось состояние кнопки, при этом текущие состояние кнопки - нажато"
У вас же "digitalRead(2)==HIGH&&flag==0" , что на человеческий язык переводится - гораздо трудней. flag - не прочитав весь остальной код - не поймешь его смысл. К тому же ... он меняется у вас там где светики мигают, а в оригинале было четко разделено "вот код работы с кнопками и принятие решений" (весь в одном месте), а вот отдельно отсылка SMS-ски :)
Не знаю ваш уровень english, но возможно вы просто не поняли откуда взялись эти названия переменных, поэтому они вам "ничего не сказали" (а нужно старатся что-бы код "сам рассказывал что делает").
prev - сокращение от "previous - предыдущий".
Btn - сокращение от "Button - кнопка"
curr - сокращение от "current - текущие, нынешнее (состояние)"
Следовательно когда я вижу prevBtn и currBtn я сразу читаю "прошлое состояние кнопки", и "текущие состояние кнопки" :)
А когда я вижу flag - я понимаю только что это какая-то переменная принимающая true/false. Семантика ее - прошла мимо меня.
Так что попробуйте, все-таки условия "кнопку нажали" и "кнопку отпустили" переписать в стиле вашего изначального скетча. Он вообщем-то был "хорошим примером". C говорящими именами переменных и без "размазывание" кнопочной логика в разные места :)
да никому я не собирался выносить мозг!!! Вас никто не заставлял отвечать в ветке! если для Вас это тупые вопросы, зачем было отвечать на них? И вообще, мы здравые люди и я думаю эти споры и разборки ни к чему..
И тем неменее, ВЫ на провокацию повелись и решили нам доказать что не лапти щи хлебаете и полезли лопатить код своими ручками:)
Так что миссия удалась, welcome aboard. гы гы
А про шоколадку вы здря, собак не кормят шоколадом, для собак шоколад это смерть.. Эт я просто вспомнил как Шелдон тренировал Пени в Теории большого взрыва.. :)
Далее, смотрите, у вас в скетче затесался "аттавизм" от оригинально.
При этом, в коде оно нигде не используется.
А сама идея - хорошая. analogRead(2) - фиг его пойми что значит, а когда читаешь analogRead(btnPin) - сразу понимаеш что это чтение состояние кнопки :)
Второй плюс, когда номера пинов вынесены в одно место и имеют имена... если вам потребовалось перенсти кнопку на другой пин, то в случае если у вас было
в 30-ти местах, и вы вдруг решили перевесить светик на 13-тый пин, то вам нужн обудет менять в 30-ти местах код. Внимательно. Нигде не пропустить. Если же вы изначально сделали
То поменять номер пина нам нужно будет только в одном месте. Да и читать такое легче. Сразу понятно "включили красный светодиод" :)
Только я бы, наверное даже не "переменную делал" под номер пина, а ключевым словом #define воспользовался
#define RED_LED_PIN 7 #define GREEN_LED_PIN 8 setup(){ pinMode(RED_LED_PIN,OUTPUT); pinMode(GREEN_LED_PIN,OUTPUT); } loop(){ .... digitalWrite(RED_LED_PIN,HIGH); // включили красный светодиод digitalWrite(GREEN_LED_PIN,LOW); // выключили зеленый ... }Ползем далее. Смотрим на функции Comand_high() и Command_low()
Если вы смогли выкинуть из них вашу переменную flag, то они стали отличатся только одной вещью - номером пина которым они мигают :)
Следовально, вместо двух функций, мы можем использовать одну. А номер пина - передавать в нее параметром. ну и назовем ее попонятней.
blinkLed - мигать светодиодом.
void blinkLed(byte ledPin) { digitalWrite(ledPin, HIGH); delay(300); digitalWrite(ledPin,LOW); delay(300); digitalWrite(ledPin, HIGH); delay(300); digitalWrite(ledPin, LOW); }А использовать ее будем так:
Смотрим на наш blinkLed и понимаем что он не идеален :)
А если нам нужно будем мигнуть 100-ть раз? Что так и будем 100 раз копировать digitalWrite/delay?
Тут нам поможет for
void blinkLed(byte ledPin) { for(byte i=0;i<2;i++){ // мигнуть два раза digitalWrite(ledPin, HIGH); delay(300); digitalWrite(ledPin,LOW); delay(300); } }P.S. Кстати - забыл вас пнуть за то отвратительное название темы. "Помогите новичку". В качестве домашнего задания - сами найдите поиском мою обычную ругань по этому поводу :)
уфф..... Puhlyaviy, где Вы там со своей водой в бутылке с разбрызгивателем?...
пытаюсь "переварить" написанное leshak...
тяжеловото..
тяжеловото..
процес формирования новых связей в мозгу всегда тяжело проходит.. потом легче пойдет... главно начать.. ( допивает воду из бутылки)
тяжеловото..
Первый раз и на бабу влезть не просто... зато потом :)
Не пытайтесь переварить "сразу все". Не хватайтесь перепахивать сразу весь скетч.
Каждый шаг что я описывал - подразумевает что мы в его начале и конце имеем рабочий скетч. Более того - "внешнее поведение" даже не меняется. Так что пытайтесь применять эти советы "по очереди", а не все сразу. Для начала - вернитесь, к prevBtn/currBtn. Там всего пару строчек вам поменять прийдется (а свои функции мигания диодом - оставте "как есть").
Универсалить - так универсалить! Домашнее задание разобраться нафига я это изменил и почему такие типы.
void blinkLed(byte ledPin, int blinkCount, long blinkDelay) { for(byte i=0;i<blinkCount;i++){ // намигаться по самое нехочу digitalWrite(ledPin, HIGH); delay(blinkDelay); digitalWrite(ledPin,LOW); delay(blinkDelay); } }ПС: "100-ть" - блин! Как это прочитать? Ничего умнее "Хундырть" в глову не идет :)
2 leshak, да вот по очереди и пытаюсь все соображать..
=========
Далее, смотрите, у вас в скетче затесался "аттавизм" от оригинально.
1intbtnPin = 2;===========
тут вкурил.. что надо было вот так:
2 JollyBiber сам затормозил на этом месте )))
И да... у вас сейчас могут быть проблемы с детектом "нажали/отпустили" кнопку. Пока светоиод мигает - ардуина забивает болт на изменение состояния кнопок.
Пока и вы, забейте болт на эту проблему. Нажимйте отпускайте кнопку с интервалом 2-3-секунды. Когда светики уже отмигали.
Пусть, вначале, хоть так заработает.
А уж потом - вернем к этой проблеме, устраним "тупняки" :)
2 leshak, да вот по очереди и пытаюсь все соображать..
Не нужно "соображать", нужно делать. По одному шагу. Следующий шаг опирается на предыдущий. Когда вы сделаете в коде, вам проще будет понять что делать в следующем. Навык "представить как будет выглядит скетч после 5-ти изменений" - он позже прийдет :)
>тут вкурил.. что надо было вот так
Угу. Только вначале нужно было избавится от неудачного flag :) и убрать digitalRead из условия. Предыдущий шаг пропустили :( Вернитесь к истокам - смотрите как это было сделано в стартовом скетче. Первое условие - вам даже менять не нужно было. А второй if - написать полностью "по аналогии".
Универсалить - так универсалить!
Не... тут пока универсалить особо не нужно. Мы же все равно будем ее переделывать на "без delay()"
Да и это все-таки "временно вспомогательная функция". Потом же у нас будет заменятся на sendSMS
IMHO то что уже есть "достаточно универсально": передачу параметра - показали, использование for - попробовали, вынос конфигурации пинов в дефайны - тоже есть. Не стоит мучать далее :)
Домашнее задание разобраться нафига я это изменил и почему такие типы.
Тогда я и вам домашнее задание задам: перечитать документацию на функцию delay и подумать так ли уж идеально вы выбрали типы :) По крайней мере один из них.
Update: даже два. Слабо мигнуть минус 3 раза? :)
получилось... но надо идти за пивом, а то извилины уже дымлят...
int btnPin = 2; boolean prevBtn = LOW; void setup() { pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(2, INPUT); } void loop() { boolean currBtn = digitalRead(btnPin); if (prevBtn != currBtn && currBtn == HIGH) { Comand_high(); } if (prevBtn != currBtn && currBtn == LOW) { Comand_low(); } prevBtn = currBtn; }функции Comand_hight и Comand_low не писал в коде, так как пока остались прежними..
Навел порядок немного:
#define HIGH_LED_PIN 7 #define LOW_LED_PIN 8 int btnPin = 2; boolean prevBtn = LOW; void setup() { pinMode(HIGH_LED_PIN, OUTPUT); pinMode(LOW_LED_PIN, OUTPUT); pinMode(btnPin, INPUT); } void loop() { boolean currBtn = digitalRead(btnPin); if (prevBtn != currBtn && currBtn == HIGH) { Comand_high(); } if (prevBtn != currBtn && currBtn == LOW) { Comand_low(); } prevBtn = currBtn; } void Comand_high() { digitalWrite(HIGH_LED_PIN, HIGH); delay(300); digitalWrite(HIGH_LED_PIN,LOW); delay(300); digitalWrite(HIGH_LED_PIN, HIGH); delay(300); digitalWrite(HIGH_LED_PIN, LOW); } void Comand_low() { digitalWrite(LOW_LED_PIN, HIGH); delay(300); digitalWrite(LOW_LED_PIN,LOW); delay(300); digitalWrite(LOW_LED_PIN, HIGH); delay(300); digitalWrite(LOW_LED_PIN, LOW); }а вот по поводу:
voidblinkLed(byteledPin) - мне не понятно пока..Дык я же не говорил что "мой вариант беспрекословно идеальный" - это и так всем понятно ;)
Пока - зашибок.
а вот по поводу:
voidblinkLed(byteledPin) - мне не понятно пока..Смотрите. У вас есть две функции. Comand_high() и Comand_low(). Которые отличаются только одной вещью - каким пином они мигают. Во всем остальном - это дублирование кода. Которого желательно избегать (хотя-бы из лени).
То есть нам нужно написать новую функцию. Аналогичную Command_high() (почти идентичную), но каким именно пином мигать, будет зашито не в саму функцию, а мы будем сообщать ей когда делаем вызов самой функции. То есть - нам нужно научится передавать параметр в функцию.
Поэтому мы читаем Функции | Аппаратная платформа Arduino
и думаем как же написать такую функцию (или ищем ее выше по ветке :)
Кстати, передавать параметр в функцию мы уже умеем :) когда вы делаете digitalWrite(7,HIGH); вы же сообщаете функции какой пин и в какое значение нужно установить? Если бы не возможность передавать параметры, то представте сколько почти одинаковых функций пришлось бы написать авторам ардуины: digitalWrite_7_HIGH(), digitalWirte_7_LOW(), digital_8_HIGH() и т.д. и т.п. Слава богу они были ленивы и написали всего одну функцию. Которую можно использовать с разными пинами.
Теперь вам - нужно написать функцию, которая умеет принимать один параметр и использует его в качестве номера пина для мигания.
P.S. Кстати в C/C++ принято называть функции с маленькой буквы. Как-бы "джентельменское соглашение". Что-бы все было однотипно и не гадать.
правильно?
#define HIGH_LED_PIN 7 #define LOW_LED_PIN 8 int btnPin = 2; boolean prevBtn = LOW; void setup() { pinMode(HIGH_LED_PIN, OUTPUT); pinMode(LOW_LED_PIN, OUTPUT); pinMode(btnPin, INPUT); } void loop() { int i=HIGH_LED_PIN; int j=LOW_LED_PIN; boolean currBtn = digitalRead(btnPin); if (prevBtn != currBtn && currBtn == HIGH) { blinkLed(i); } if (prevBtn != currBtn && currBtn == LOW) { blinkLed(j); } prevBtn = currBtn; } void blinkLed(byte ledPin) { digitalWrite(ledPin, HIGH); delay(300); digitalWrite(ledPin,LOW); delay(300); digitalWrite(ledPin, HIGH); delay(300); digitalWrite(ledPin, LOW); }теперь попробую разобраться с функцией
voidblinkLed..Могут ли у Вас меняться значения
HIGH_LED_PIN иLOW_LED_PIN ?JollyBiber не совсем понял вопроса... или пока не понял..
кстати, применил Ваш код для функции blinkled:
получилось вот так:
#define HIGH_LED_PIN 7 #define LOW_LED_PIN 8 int btnPin = 2; boolean prevBtn = LOW; void setup() { pinMode(HIGH_LED_PIN, OUTPUT); pinMode(LOW_LED_PIN, OUTPUT); pinMode(btnPin, INPUT); } void loop() { int i=HIGH_LED_PIN; int j=LOW_LED_PIN; boolean currBtn = digitalRead(btnPin); if (prevBtn != currBtn && currBtn == HIGH) { blinkLed(i,5,300); } if (prevBtn != currBtn && currBtn == LOW) { blinkLed(j,5,300); } prevBtn = currBtn; } void blinkLed(byte ledPin, int blinkCount, long blinkDelay) { for(byte x=0;x<blinkCount;x++){ digitalWrite(ledPin, HIGH); delay(blinkDelay); digitalWrite(ledPin,LOW); delay(blinkDelay); } }2 JollyBiber помоему я понял что вы хотели сказать этим вопросом..
int i=HIGH_LED_PIN; int j=LOW_LED_PIN;это лишнее?
правильно будет вот так?
#define HIGH_LED_PIN 7 #define LOW_LED_PIN 8 int btnPin = 2; boolean prevBtn = LOW; void setup() { pinMode(HIGH_LED_PIN, OUTPUT); pinMode(LOW_LED_PIN, OUTPUT); pinMode(btnPin, INPUT); } void loop() { boolean currBtn = digitalRead(btnPin); if (prevBtn != currBtn && currBtn == HIGH) { blinkLed(HIGH_LED_PIN,5,300); } if (prevBtn != currBtn && currBtn == LOW) { blinkLed(LOW_LED_PIN,5,300); } prevBtn = currBtn; } void blinkLed(byte ledPin, int blinkCount, long blinkDelay) { for(byte i=0;i<blinkCount;i++){ digitalWrite(ledPin, HIGH); delay(blinkDelay); digitalWrite(ledPin,LOW); delay(blinkDelay); } }Правильно :) Теперь рассмотрим вариант про который писал leshak:
что сейчас произойдет?
blinkLed(LOW_LED_PIN, -5, -300);И как это победить? Подсказка>это лишнее?
Ну как-бы да. Вводить отдельную локальную переменную, вам нужно было-бы вы собирались, сделато что-то, скажем "помигать всеми диодами по очереди". Что-бы если у вас, скажем 10-ть диодов, не писать 10-ть раз blinkedLen, а сделать что-то типа
Правильно :) Теперь рассмотрим вариант про который писал leshak:
что сейчас произойдет?
blinkLed(LOW_LED_PIN, -5, -300);И как это победить? ПодсказкаЭм.. "разобратся с типами" - это хорошо. Но все-таки невозможно охватить сразу все :) Тем более что это было ваше домашние задание :)
2Life23:
Поэтому, я пока предлагаю не усложнять. Пусть у нас blinkLed принимает один параметр. Настраивать сколько раз мигать, как быстро... для текущей задачи не критично. Есть более актуальные проблемы.
Например избавление от delay() (а потом у нас "дребезг" может вылезти) :)
Вначале добъемся что-бы "работало как нужно", а уж потом будем добавлять "пасхальные яйца" :)
Вы наблюдаете, предсказанную мной проблему? Пока диод не закончил мигание - скетч ни на что не реагирует?
Если наблюдаете, то для начала попробуйте понять
а. Почему это происходит (и глядя в код попытатся предсказать точное время "тупления" :)
б. Как работает пример Мигаем светодиодом без delay() | Аппаратная платформа Arduino
Вначале хотя-бы прочитайте и разберите построчно. Вряд ли у вас получится, сразу, адаптировать его под себя (подсказка: для этого прийдется разбить blinkLed на две функции. Одна будет "устанавливать чем мигать нужно", а вторая "выполнять мигание когда пришло время"), так что "вникнуть" пока достаточно :)
Хм... кстати... по поводу ухода от реальной задачи.
Мы так бодро занялись диодами и миганиями, что забыли об изначальной задаче - отправке SMS.
Может вернемся к ней? Life23 как вы на это смотрите? Как я понимаю, вы перешли на мигание диодом, что-бы не тратить деньги на SMS, в период отладки. Но есть - более прямое решение этой задачи, показать?
а. Почему это происходит (и глядя в код попытатся предсказать точное время "тупления" :)
время "тупления" = delay(blinkDelay)+delay(blinkDelay)
то что описанно в
voidblinkLed+такты перехода.а сам "delay" останавливает все рабуту контроллера, пока не отсчитает параметр в самом dalay.естественно по первому фронту сигнала с кнопки срабатывает одно из условий:
if (prevBtn != currBtn && currBtn == HIGH) { blinkLed(HIGH_LED_PIN,5,300); } if (prevBtn != currBtn && currBtn == LOW) { blinkLed(LOW_LED_PIN,5,300);остальной "дребезг" уходит в игнор, пока выполняеться delay.
"Как я понимаю, вы перешли на мигание диодом, что-бы не тратить деньги на SMS, в период отладки."
это действительно так. плюс затрата на время проверки.
"Но есть - более прямое решение этой задачи, показать?"
был бы очень благодарен! ;)
Но все эти "уроки" очень полезны - за что очень Вам благодарен!
update: вместо св.диодов использавать терминал?
update: вместо св.диодов использавать терминал?
Точняк :)
Главная задача - заранее писать так, что бы потом, когда все отладится на Serial, перейти на использование реального шилда, с минимальными усилиями.
Для этого, мы можем применить ту же самую технику, которую использовали для "а вдруг у нас номера пинов поменяются".
Пишем вверху (чуть ниже gprsSerial(3,2))
Мы создали "псевдоним" GPRS. При компиляции он, автоматически будет заменятся на Serial
затем берем ваш изначальный скетч и везде, кроме строки SoftwareSerial gprsSerial(3, 2); заменяем gprsSerial на GPRS
У нас полчится что-то типа
и т.д.
После чего открываем Serial. и смотрим "что же там наш скет посылает шилду" :)
Когда все отладим, переключится "на настоящий шилд" мы сможем заменой одной строчки.
Поменяем
на
Кстати, подобный подход не толко деньги вам съекономит, но и.... позволит другим людям, тем у кого нет шилда - запустить/пощупать ваш код. Что, опять-таки - повысит шансы на помощь форума.
Так что - всегда старайтесь свои проблемы/примеры по возможности сводить к использованию Serial - он есть у всех :)
сильно не ругайте..
#define GPRS Serial int btnPin = 2; int i; boolean prevBtn = LOW; char* myStrings[]={"Knopka ON", "Knopka OFF"}; void setup() { GPRS.begin(9600); delay(100); } void loop() { boolean currBtn = digitalRead(btnPin); if (prevBtn != currBtn && currBtn == HIGH) { i=0; sendTextMessage(); } if (prevBtn != currBtn && currBtn == LOW) { i=1; sendTextMessage(); } prevBtn = currBtn; } void sendTextMessage() { GPRS.println(myStrings[i]); delay(1000); }использовал все что знаю на данный момент..
можно сэкономить переменную "i" Выкиньте ее и подправьте функцию
sendTextMessage ;)А следующий ход - вернуть ее назад и убрать sendTextMessage из "if"-ов ;)
Не, ну че.. нормалек.
Только...
шо же вы так укоцали sendTextMessage()? Выкинули из нее все что только можно?
Если вы сейчас подмените Serial на настоящий gprsSerial - оно же не заработает.
Пусть будут все эти "AT+CMGF=1\r". Если вы их увидите в Serial Monitor вы же не убежите с криком "мама, чтоо это.."? ;)
Наоборот, получите уверенность что "вот... нужные служебные команды тоже отсылаются". Среди них - и свои "Knopka ON" и "Knopka Off" увидите.
Вам же нужно все отладить так, что-бы потом только "поменяв одну строчку" запустить все на реальном железе. Поэтому чем ближе к реальности будет скетч, чем меньше прейдется "дописывать/менять" при переходе к реальности - тем лучше (и потом еще не раз, возможно прийдется обратно "от реального" к "отладочному" варианту возвращатся. если какие-то "косяки" вылезут).
То что индекс строки вы передаете в фунцию с помощью глобальной переменно i это...
Молодец, конечно, выкрутился :) Работать будет. Только шо же мы так параметров функции боимся? Они не кусаются. Вроде же, уже, когда писали blinkLed то передавали пин которым нужно мигать в качестве параметра. Почему тут так же не сделать?
Сделайте что-бы вместо двух строк
Можно было написать одну
И переменную i - вообще выкинуть.
Кстати - неудачно вы ей имя дали. Традиционно переменные i,j используется в качестве итераторов (счетчиков) когда мы проходим по массиву с помощью for. Поэтому любой читающий код, и видящий что-то myStrings[i] интуитивно ищет глазами цикл :)
Имя, скажем messageIndex или messageIdx или msgIdx - было-бы гораздо более подходящим :)
покоцал - что бы легче понимать принцип работы программы. Да и на форум не засорять.. Конечно я понимаю, что реальный шилд не будет работать с таким кодом. Перед тем как вставить код на форуме, я 100 раз проверил работу полного кода.
по поводу переменной i сам уже понял, что она в основном используеться в счетчиках.. :)
а с параметрами функции деуствительно пока "страхи" :)).
но вижу не миновать мне их никак... пока разобрался с char и как правильно вписать ее в serial.print - запутался совсем..
перекур - и иду дальше в сторону "параметров функции"))
А следующий ход - вернуть ее назад и убрать sendTextMessage из "if"-ов ;)
А вот это - не нужно.
мдаа.. действительно не стоит бояться пераметров функции.. ))
#define GPRS Serial int btnPin = 2; boolean prevBtn = LOW; char* myStrings[]={"Knopka ON", "Knopka OFF"}; void setup() { GPRS.begin(9600); delay(100); } void loop() { boolean currBtn = digitalRead(btnPin); if (prevBtn != currBtn && currBtn == HIGH) { sendTextMessage(0); } if (prevBtn != currBtn && currBtn == LOW) { sendTextMessage(1); } prevBtn = currBtn; } void sendTextMessage(int sms) { GPRS.println(myStrings[sms]); delay(1000); }