Ви не увійшли.
Сторінки 1
Добрий день. Малу по малу вивчаю ардуіно і зіткнувся з проблемою. Ось так зараз виглядає мій код, оснований на схрещенні прикладів з мережі. Все працює начебто, але при виконанні затримок втрачається зв'язок з контролером через Delay. Тобто неможливо зупинити виконання циклу кнопкою на вебсторінці. Мені порадили приклад за посиланням, але я не можу його адаптувати під себе, не вистачає кеби зібрати все до купи.
http://arduino.ru/tutorials/BlinkWithoutDelay
#include <SPI.h>
#include <Ethernet.h>
boolean newInfo = 0;
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 };
IPAddress ip(192,168,4,70);
byte gateway[] = { 192, 168, 4, 1 };
byte subnet[] = { 255, 255, 255, 0 };
EthernetServer server(80);
void setup()
{
pinMode(8, OUTPUT);
digitalWrite(8,HIGH);
Ethernet.begin(mac, ip);
server.begin();
Serial.begin(9600);
}
void blinker()
{
digitalWrite(8, LOW);
delay(8000);
digitalWrite(8, HIGH);
delay(5000);
digitalWrite(8, LOW);
delay(8000);
digitalWrite(8, HIGH);
delay(10000);
digitalWrite(8, LOW);
delay(180000);
digitalWrite(8, HIGH);
}
void loop()
{
EthernetClient client = server.available();
if(client){
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if(newInfo && c == ' '){
newInfo = 0;
}
if(c == '$'){
newInfo = 1;
}
if(newInfo == 1){
Serial.println(c);
if(c == '1'){
Serial.println("ON");
digitalWrite(8, LOW);
blinker();
}
if(c == '2'){
Serial.println("OFF");
digitalWrite(8, HIGH);
}
}
if (c == '\n') {
currentLineIsBlank = true;
}
else if (c != '\r') {
currentLineIsBlank = false;
}
if (c == '\n' && currentLineIsBlank) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println("Refresh: 30");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print("<title>Alarm</title>");
client.print("<H1>Block 1</H1>");
client.print("<a href=\"/$1\"><button>On</button></a>");
client.print("<a href=\"/$2\"><button>Off</button></a>");
client.println("<br />");
client.println("</html>");
break;
}
}
}
delay(1);
client.stop();
}
}
Неактивний
1) Микроконтроллер - это не компьютер. Он выполняет все команды строго в той последовательности, которую Вы ему задаёте в своей программе. Здесь нет операционной системы, которая сама распараллеливает выполняющиеся задачи. Поэтому Вам и предложили разобраться в примере, который показывает, как сделать псевдо-параллельное выполнение разных задач при последовательно выполняющейся программе.
2) Ваша программа - это конечно хорошо, но в Вашем посте нет ни слова о том, что и как она должна делать. Может всё именно так и задумано, как написано? С этой точки зрения в Вашей программе нет никаких ошибок и всё работает именно так, как и запланировано!
Єдина проблема стоїть у неможливості виконання аварийного зупинення, поки не відпрацюють всі затримки. Навіщо там кнопка "OFF" якщо вона все одно не працює? А мені потрібно щоб функціонувало.
Остання редакція UW5EGA (2020-10-29 15:35:46)
Неактивний
Если в общих чертах ,то вводите дополнительную переменную (флаг), устанавливаете ее в какое-то значение и дальше:
если (флаг разрешен) то if currentmillis-prevmillis>=interval выполняете то что вам нужно
Неактивний
Все равно не понимаю как это все написать. Нужен букварь.
Странно, сервер подняли, кнопочки к нему прикрутили, а элементарные if-ы написать не можете?
delay(180000) большая пауза, смотрите, пример BlinkWithoutDelay
UW5EGA пише:Все равно не понимаю как это все написать. Нужен букварь.
Странно, сервер подняли, кнопочки к нему прикрутили, а элементарные if-ы написать не можете?
Так это украдено на просторах интернета из разных статей.
Неактивний
Судя по всему, когда выполняется delay(), весь остальной код просто останавливается и ждет возврата из функции, которая вызвала delay(). Чтобы blinker() работал, как ожидается, вся программа должна быть переписана в виде обработчиков асинхронных прерываний, тогда delay() может быть прерван в любой момент.
Вместо этого предлагается управлять светодиодом, синхронизировав его с часами, которые идут независимо от delay(). Таким образом каждый раз loop() будет иметь возможность оценить значение таймера и принять решение, как переключить светодиод. Например, если таймер меньше значения X, то светодиод зажечь. Если больше - погасить. Подробнее:
https://www.arduino.cc/en/Tutorial/Buil … thoutDelay
Для воспроизведения более сложной последовательности можно запомнить время начала этой последовательности, а затем зажигать или гасить светодиод по прошествии определенного времени относительно начала. При этом сам код переключения светодиода должен выполняться при каждом цикле loop():
#define BLINKER_NOTIME -1
void()
{
unsigned long currentms = millis();
long long blinkerstartms;
// ... some blinker related event happened ...
switch (event) {
case BLINKER_ON_EVT:
// engage the blinker()
blinkerstartms = currentms;
break;
case BLINKER_OFF_EVT:
blinkerstartms = BLINKER_NOTIME;
break;
default:
// nothing to do
}
if (blinkerstartms != BLINKER_NOTIME)
blinkerstartms = blinker(blinkerstartms, currentms);
}
long long
blinker(unsigned long startms, currentms)
{
// defined as offsets cumulative 0 + 8000 + 5000 + 8000 + 10000 + 18000
unsigned int blinkms[] = {0, 8000, 13000, 21000, 31000, 49000};
if (startms < 0)
return BLINKER_NOTIME;
// invert the blinker every time it reaches the next blinkms value
for (i = 0; i < sizeof(blinkms)/sizeof(blinkms[0]); i++) {
// TODO: handle the timer overflows
if (blinkms[i] >= startms - currentms) {
digitalWrite(LED_ADDR, i % 2 ? LOW : HIGH);
return startms;
}
// we're done with the blinkms[] array - shut the blinker down
return BLINKER_NOTIME;
}
Извините, никогда не писал для Ардуино, но идею, надеюсь, передать удалось.
Остання редакція Mishka (2020-11-02 15:54:04)
Неактивний
пробуйте так
#include <SPI.h>
#include <Ethernet.h>
boolean newInfo = 0;
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 };
IPAddress ip(192, 168, 4, 70);
byte gateway[] = { 192, 168, 4, 1 };
byte subnet[] = { 255, 255, 255, 0 };
EthernetServer server(80);
unsigned long previousMillis = 0;
unsigned long currentMillis;
boolean flag1, flag2, flag3, flag4, flag5;
bool state = false;
bool ledstate;
unsigned long t1 = 8000;
unsigned long t2 = 5000;
unsigned long t3 = 10000;
unsigned long t4 = 18000;
void setup()
{
pinMode(8, OUTPUT);
digitalWrite(8, HIGH);
Ethernet.begin(mac, ip);
server.begin();
Serial.begin(9600);
}
void blinker() {
ledstate=digitalRead(8);
if (!flag1 && (millis() - previousMillis >= t1)) {
digitalWrite(8, !ledstate);
flag1 = 1;
flag2 = 0;
previousMillis = millis();
}
if (!flag2 && (millis() - previousMillis >= t2)) {
digitalWrite(8, !ledstate);
flag2 = 1;
flag3 = 0;
previousMillis = millis();
}
if (!flag3 && (millis() - previousMillis >= t1)) {
digitalWrite(8, !ledstate);
flag3 = 1;
flag4 = 0;
previousMillis = millis();
}
if (!flag4 && (millis() - previousMillis >= t3)) {
digitalWrite(8, !ledstate);
flag4 = 1;
flag5 = 0;
previousMillis = millis();
}
if (!flag5 && (millis() - previousMillis >= t4)) {
digitalWrite(8, !ledstate);
flag5 = 1;
previousMillis = millis();
}
}
void loop()
{
state = digitalRead(8);
EthernetClient client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (newInfo && c == ' ') {
newInfo = 0;
}
if (c == '$') {
newInfo = 1;
}
if (newInfo == 1) {
Serial.println(c);
if (c == '1') {
state = true;
flag1 = 0;
digitalWrite(8, LOW);
previousMillis = millis();
Serial.println("ON");
}
if (c == '2') {
Serial.println("OFF");
digitalWrite(8, HIGH);
state = false;
}
}
if (state == true) {
blinker();
}
if (!state) {
flag1 = 1;
flag2 = 1;
flag3 = 1;
flag4 = 1;
flag5 = 1;
}
if (c == '\n') {
currentLineIsBlank = true;
}
else if (c != '\r') {
currentLineIsBlank = false;
}
if (c == '\n' && currentLineIsBlank) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println("Refresh: 30");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print("<title>Alarm</title>");
client.print("<H1>Block 1</H1>");
client.print("<a href=\"/$1\"><button>On</button></a>");
client.print("<a href=\"/$2\"><button>Off</button></a>");
client.println("<br />");
client.println("</html>");
break;
}
}
}
delay(1);
client.stop();
}
}
Неактивний
Судя по всему, когда выполняется delay(), весь остальной код просто останавливается и ждет возврата из функции, которая вызвала delay(). Чтобы blinker() работал, как ожидается, вся программа должна быть переписана в виде обработчиков асинхронных прерываний, тогда delay() может быть прерван в любой момент.
Вместо этого предлагается управлять светодиодом, синхронизировав его с часами, которые идут независимо от delay(). Таким образом каждый раз loop() будет иметь возможность оценить значение таймера и принять решение, как переключить светодиод. Например, если таймер меньше значения X, то светодиод зажечь. Если больше - погасить. Подробнее:
https://www.arduino.cc/en/Tutorial/Buil … thoutDelay
Для воспроизведения более сложной последовательности можно запомнить время начала этой последовательности, а затем зажигать или гасить светодиод по прошествии определенного времени относительно начала. При этом сам код переключения светодиода должен выполняться при каждом цикле loop():
Извините, никогда не писал для Ардуино, но идею, надеюсь, передать удалось.
Я много чего понимаю, но написать сом не в состоянии.
Неактивний
ard125 пише:пробуйте так
Но к сожалению задержки не работают, реле включается и выключается без задержек.
У меня нет пока eternet-модуля, поэтому проверить полностью код не могу, возможно где-то есть ошибка. Но от обычной кнопки в простеньком коде у меня все работает.
unsigned long previousMillis = 0;
unsigned long currentMillis;
boolean flag1, flag2, flag3, flag4, flag5;
bool flag_btn1, flag_btn2 = false;
bool state = false;
bool ledstate;
unsigned long t1 = 8000;
unsigned long t2 = 5000;
unsigned long t3 = 10000;
unsigned long t4 = 18000;
void setup() {
pinMode(5, INPUT_PULLUP);
pinMode(8, OUTPUT);
digitalWrite(8, HIGH);
Serial.begin(9600);
}
void blinker() {
ledstate = digitalRead(8);
if (!flag1 && (millis() - previousMillis >= t1)) {
digitalWrite(8, !ledstate);
flag1 = 1;
flag2 = 0;
previousMillis = millis();
}
if (!flag2 && (millis() - previousMillis >= t2)) {
digitalWrite(8, !ledstate);
flag2 = 1;
flag3 = 0;
previousMillis = millis();
}
if (!flag3 && (millis() - previousMillis >= t1)) {
digitalWrite(8, !ledstate);
flag3 = 1;
flag4 = 0;
previousMillis = millis();
}
if (!flag4 && (millis() - previousMillis >= t3)) {
digitalWrite(8, !ledstate);
flag4 = 1;
flag5 = 0;
previousMillis = millis();
}
if (!flag5 && (millis() - previousMillis >= t4)) {
digitalWrite(8, !ledstate);
flag5 = 1; state = false;
previousMillis = millis(); Serial.println("Stop ");
}
}
void loop() {
if (digitalRead(5) == LOW && !flag_btn1) {
Serial.println("Start ");
state = true;
flag_btn1 = 1;
flag1 = 0; previousMillis = millis();digitalWrite(8, LOW);
}
if (state == true) {
blinker();
}
if (digitalRead(5) && flag_btn1) flag_btn1 = 0;
if (!state) {
flag1 = 1;
flag2 = 1;
flag3 = 1;
flag4 = 1;
flag5 = 1;
}
}
кнопка подключена к 5 пину. Замыкается на землю.
Остання редакція ard125 (2020-11-10 11:38:06)
Неактивний
Давайте я вам бесплатно отправлю ethernet shield для опытов?
Очень странно стало вести себя, после включения первая задержка где-то 3 минуты, потом 10 секунд пауза и снова включилось на долго но я уже не стал засекать время.
Неактивний
Сторінки 1