Программа внутри millis()

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Ситуация следующая, внутри цикла millis не выполняются функции (кроме передачи данных в консоль Processing).

Что не так?

 int currentMillis = millis();
  if (currentMillis - previousMillis > interval){
    
  if (t != null) {DHT22T=float(t);}       //Преобразование
  if (h != null) {DHT22H=float(h);}       //чисел из строчного массива
  if (t0 != null) {DS18B20T1=float(t0);} //в переменную
  if (t1 != null) {DS18B20T2=float(t1);} //с плавающей запятой
  if (temperature_up != null) {Tmax=float(temperature_up);}
  if (temperature_down != null) {Tmin=float(temperature_down);}
  if (humdity != null) {Hmax=float(humdity);}  
    
  row_data=hr+":"+min+"_"+day+"_"+month+"   "+"T1: "+DHT22T+" T2: "+DS18B20T1+" T3: "+DS18B20T2+" H: "+DHT22H;
  save.println(row_data);
  println (row_data);
     
  xk=xn+432*1000/interval;
  yk=yn-240.0*DHT22T/(10*(Tmax-Tmin));
  stroke(255, 0, 0); // цвет будущей линии красный
  line (xn, yn, xk, yk); // рисуем линию  
  xn=xk;
  yn=yk;
  
  previousMillis = currentMillis;
 } 

 

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Интересный момент: при интервале меньше 1000 millis (1 секунда), по крайней мере лог файл видется, но мне такая частота не нужна, желаемый интервал раз в 30-60 минут.

step962
Offline
Зарегистрирован: 23.05.2011

Я бы попробовал определить соответствующие переменные не как int, а как long.

Вдруг да поможет...

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

step962 пишет:

Я бы попробовал определить соответствующие переменные не как int, а как long.

Вдруг да поможет...

 

домой приду попробую, спасибо за совет.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

long не помог...

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Прошу помощи. Хотя бы направление укажите.

leshak
Offline
Зарегистрирован: 29.09.2011

Во первых, читаем внимательно докуменатацию на millis() | Аппаратная платформа Arduino  и видим, что она возвращает тип unsigned long, а не int или long. Вообщем тут не гадать нужно о типе, а в доки смотреть :)

Следовательно, для хранения и оперирования значениями которые она возвращает, все переменные должны быть того же типа. Так что убедитесь, что вы не толко у currentMillis сменили тип, но и у previousMillis, interval и т.п. все в которые может "попасть время".

Во вторых, попробуйте сузить область поиска бага. Выяснить что именно у вас глючит "таймерная логика" или "код внутри нее".

Выкинте все внутри этого if-а, и сделайте там какой-то баланльный Serial.println(currentMillis). Если в сериал логе будете видить что он вызывается нормально и вовремя - почастям возвращайте все что выкинули и смотрите  когда опять появятся глюки.

Проверте что у вас правильно объявлен previuseMillis (либо как статическая, либо как глобальная переменная), что его значение не теряется между вызовами loop()   (вообщем бага может быть спрятана в коде который вы не показали).

Для более удобного тестирования, что-бы не ждать по пол-часа, можно провернуть такую хитрость:

Делаем объявление:

#define GET_TIME (millis()*100UL)

Везде в коде, вызовы millis() заменяем на GET_TIME  (без скобочек).

В результате мы получим "ускоренное время". Для кода будет казатся что время пошло в 100 раз быстрей и ждать нам нужно будет не пол-часа, а 18-ть секунд (если слишком быстро, меняем коэфициент 100 на что-то поменьше).

Когда все заработает, достаточно будет закоментить этот дефайн и вместо него написать

#define GET_TIME millis()

Что-бы вернуть "обычный маштаб времени". Без необходимости "менять везде по коду на millis()". Чем снизим вероятность внести ошибку в уже отлаженный код :)

slavka
Offline
Зарегистрирован: 18.06.2013

ну может тогда unsigned long

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

leshak пишет:

Во первых, читаем внимательно докуменатацию на millis() | Аппаратная платформа Arduino  и видим, что она возвращает тип unsigned long, а не int или long. Вообщем тут не гадать нужно о типе, а в доки смотреть :)

Следовательно, для хранения и оперирования значениями которые она возвращает, все переменные должны быть того же типа. Так что убедитесь, что вы не толко у currentMillis сменили тип, но и у previousMillis, interval и т.п. все в которые может "попасть время".

Во вторых, попробуйте сузить область поиска бага. Выяснить что именно у вас глючит "таймерная логика" или "код внутри нее".

Выкинте все внутри этого if-а, и сделайте там какой-то баланльный Serial.println(currentMillis). Если в сериал логе будете видить что он вызывается нормально и вовремя - почастям возвращайте все что выкинули и смотрите  когда опять появятся глюки.

Проверте что у вас правильно объявлен previuseMillis (либо как статическая, либо как глобальная переменная), что его значение не теряется между вызовами loop()   (вообщем бага может быть спрятана в коде который вы не показали).

Для более удобного тестирования, что-бы не ждать по пол-часа, можно провернуть такую хитрость:

Делаем объявление:

#define GET_TIME (millis()*100UL)

Везде в коде, вызовы millis() заменяем на GET_TIME  (без скобочек).

В результате мы получим "ускоренное время". Для кода будет казатся что время пошло в 100 раз быстрей и ждать нам нужно будет не пол-часа, а 18-ть секунд (если слишком быстро, меняем коэфициент 100 на что-то поменьше).

Когда все заработает, достаточно будет закоментить этот дефайн и вместо него написать

#define GET_TIME millis()

Что-бы вернуть "обычный маштаб времени". Без необходимости "менять везде по коду на millis()". Чем снизим вероятность внести ошибку в уже отлаженный код :)

Спасибо!

 

Начал проверять, и понял, что вы маленько не до поняли. Это скетч Processinga, а в нем millis, цитирую 

Цитата:

 

Name

millis()

Examples
void draw() {
  int m = millis();
  noStroke();
  fill(m % 255);
  rect(25, 25, 50, 50);
}
Description Returns the number of milliseconds (thousandths of a second) since starting the program. This information is often used for timing events and animation sequences.
Syntax
millis()
Returns int

в процессинге возвращает значение int. но я по пробовал и long. ничего не поменялось. Убрал все ifы, сделал печать current в консоль процессинга и значение одной переменной. В консоль печатает, а в файл так и не пишет.

 

Приведу весь код скетча PROCESSINGA для Вашего анализа. Сам справиться не могу, нуждаюсь в подсказках.

import processing.net.*;
PImage IMG;

Client client;
long interval = 10000;
long previousMillis = 0;
float xn=50; // переменная координаты X начала
float yn=590; // переменная координаты Y начала  
float xk=0; // переменная координаты X конца
float yk=0; // переменная координаты Y конца  
float DHT22T, DHT22H, DS18B20T1, DS18B20T2,Tmax, Tmin, Hmax;
String h= "";
String t= "";
String t0= "";
String t1= "";
String temperature_up= "";
String temperature_down= "";
String humdity= "";
String filename, row_data;
String IP;
char flag=10;
PrintWriter save;
BufferedReader load;

void setup() 
{
  size(1024, 640);
  IMG = loadImage ("fon.jpg");
  client = new Client(this, "88.85.206.140", 82);
  delay(3000);
  int min = minute(); 
  int hr = hour();    
  int day = day();
  int month = month();
  int year = year();
  client.write ("1");
  filename = "DataLogger_"+hr+"_"+min+"_"+day+"_"+month+"_"+year+".txt";
  save = createWriter(filename);
}

void draw() 
{
int sec = second();  // Values from 0 - 59
int min = minute();  // Values from 0 - 59
int hr = hour();    // Values from 0 - 23
int day = day();
int month = month();
int year = year();
background(255); //цвет фона
  image(IMG,0,0);
  
 while (client.available()>0){
    char ch = client.readChar();
 
      delay(20);
    if (ch == 't') {t = client.readStringUntil(flag);}
      delay(20);  
    if (ch == 'h') {h = client.readStringUntil(flag);}
    delay(20);  
    if (ch == 1) {t0 = client.readStringUntil(flag);}
    delay(20);  
    if (ch == 2) {t1 = client.readStringUntil(flag);}
    delay(20);  
    if (ch == 3) {temperature_up = client.readStringUntil(flag);}
    delay(20);  
    if (ch == 4) {temperature_down = client.readStringUntil(flag);}
    delay(20);  
    if (ch == 5) {humdity = client.readStringUntil(flag);}
        
    
     }
   
   
  //Запись в лог файл
  long currentMillis = millis();
  if (currentMillis - previousMillis > interval){
    
  println (currentMillis);  
  println (previousMillis); 
  println (float(t)); 
  save.println (float(t));  
  //if (t != null) {DHT22T=float(t);}       //Преобразование
  //if (h != null) {DHT22H=float(h);}       //чисел из строчного массива
  //if (t0 != null) {DS18B20T1=float(t0);} //в переменную
  //if (t1 != null) {DS18B20T2=float(t1);} //с плавающей запятой
  //if (temperature_up != null) {Tmax=float(temperature_up);}
 // if (temperature_down != null) {Tmin=float(temperature_down);}
 // if (humdity != null) {Hmax=float(humdity);}  
    
  //row_data=hr+":"+min+"_"+day+"_"+month+"   "+"T1: "+DHT22T+" T2: "+DS18B20T1+" T3: "+DS18B20T2+" H: "+DHT22H;
  //save.println(row_data);
 // println (row_data);
     
  //xk=xn+432*1000/interval;
 // yk=yn-240.0*DHT22T/(10*(Tmax-Tmin));
  //stroke(255, 0, 0); // цвет будущей линии красный
  //line (xn, yn, xk, yk); // рисуем линию  
  //xn=xk;
  //yn=yk;
  
  previousMillis = currentMillis;
  
 } 
  
    //Заголовки
  fill (0, 0, 0);
  textSize(35);
  text("Заданные нормы", 80, 40);
  text("температуры и влажности", 10, 80);
  text("Действительные значения", 562, 40);
  text("температуры и влажности", 562, 80);
  textSize(25);
  text("Датчик1", 580, 120);
  text("Датчик2", 740, 120);
  text("Датчик3", 900, 120);
  text("Верхняя  температурная граница:", 10, 120);
  text("Нижняя  температурная граница:", 10, 155);
  text("Максимум влажности воздуха:", 10, 190);
  textSize(30);
  text("С", 675, 160);
  text("С", 835, 160);
  text("С", 995, 160);
  text("%", 675, 200);
  textSize(25);
  text("С", 475, 120);
  text("С", 475, 155);
  text("%", 475, 190);
  textSize(20);
  text("о", 665, 145);
  text("о", 825, 145);
  text("о", 985, 145);
  textSize(15);
  text("о", 470, 105);
  text("о", 470, 140);
  //Вывод заданных значений
  
  //Вывод действительных значений
  fill (0, 0, 0);
  textSize(30);
  if (t != null) {text(t, 580, 160);}
  if (t != null) {text(t0, 740, 160);}
  if (t != null) {text(t1, 900, 160);}
  if (h != null) {text(h, 580, 200);}
  textSize(25);
  if (temperature_up != null) {text(temperature_up, 435, 120);}
  if (temperature_down != null) {text(temperature_down, 435, 155);}
  if (humdity != null) {text(humdity, 435, 190);}
    
  //установка Даты и Времени
  textSize(30);
  if (hr<10) {
    text("0", 10, 240);
    text(hr, 30, 240);}
    else {
  text(hr, 10, 240);}
  text (":", 50, 240);
  if (min<10) {
    text("0", 60, 240);
    text(min, 80, 240);}
    else{
  text(min, 60, 240);}
  text(":", 100,240);
  if(sec<10) {
   text ("0", 110, 240);
    text (sec, 130, 240);}
    else {
  text(sec, 110, 240);}
  if(day<10) {
    text ("0", 180, 240);
    text (day, 200, 240);}
    else {
  text(day, 180, 240);}    
  text (".", 220, 240);
  if (month<10) {
    text ("0", 230, 240);
    text (month, 250, 240);}
    else {
  text (month, 230, 240);}
  text (".", 270, 240);
  text (year, 280, 240);
 
 //Конец установки Даты и Времени    
 // delay(1000);
  }

 

leshak
Offline
Зарегистрирован: 29.09.2011

> В консоль печатает, а в файл так и не пишет.

Значит у вас проблема не с millis(),  а с записью в файл.

Поэтому выкидываем все (чтение Serial и т.п.) и вначале добиваемся что в файл писалось... ну хоте бя текущие значение millis() :)

Я, честно говоря, именно с процессингом работал очень мало (чуть меньше года назад, пару дней :) , для какой-то ветки пример делал), но общие соображения будут такие (про что документацию почитать нужно):

1. Держать, особенно на таких временных интревалах, файл все время открытм для записи - очень плохая идея :(  Лучше, когда пришло время, отрыть файл, записать туда что нужно, и закрыть его. Открывать его - нужно в режиме Append, естественно, что-бы не перетерать существующие содержимое.

2. Проблема может быть так же в том что нужно еще делать flush файлу (сбрасывать кешь-буфер). Если будете файл закрывать, то возможно это не потребуется. По идее при закрытии должен сам сбрасывать буфер на диск, но.... в официальном туториале, они делают, все-таки это руками Learning Processing: Tutorials: External Data into Processing I

3. На всякий случай, убедитесь что тот Viewer которым вы смотрите файл не блокирует его на запись. Такое тоже бывает - открыл файл "посмотреть" и никто не может в него ничего записать :(  (из-за криворукости автора viewer-а, или вы смотрите каким-то редактором).

 

 

 

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

leshak пишет:

> В консоль печатает, а в файл так и не пишет.

Значит у вас проблема не с millis(),  а с записью в файл.

Поэтому выкидываем все (чтение Serial и т.п.) и вначале добиваемся что в файл писалось... ну хоте бя текущие значение millis() :)

Я, честно говоря, именно с процессингом работал очень мало (чуть меньше года назад, пару дней :) , для какой-то ветки пример делал), но общие соображения будут такие (про что документацию почитать нужно):

1. Держать, особенно на таких временных интревалах, файл все время открытм для записи - очень плохая идея :(  Лучше, когда пришло время, отрыть файл, записать туда что нужно, и закрыть его. Открывать его - нужно в режиме Append, естественно, что-бы не перетерать существующие содержимое.

2. Проблема может быть так же в том что нужно еще делать flush файлу (сбрасывать кешь-буфер). Если будете файл закрывать, то возможно это не потребуется. По идее при закрытии должен сам сбрасывать буфер на диск, но.... в официальном туториале, они делают, все-таки это руками Learning Processing: Tutorials: External Data into Processing I

3. На всякий случай, убедитесь что тот Viewer которым вы смотрите файл не блокирует его на запись. Такое тоже бывает - открыл файл "посмотреть" и никто не может в него ничего записать :(  (из-за криворукости автора viewer-а, или вы смотрите каким-то редактором).

 

 

 

 

Пунктом №1 навели на мысль. Стал очищать буфер  save.flush (); // записывает данные, оставшиеся в файл

 

Спасибо за помощь!

leshak
Offline
Зарегистрирован: 29.09.2011

ingener.solovyev пишет:

Пунктом №1 навели на мысль. Стал очищать буфер  save.flush (); // записывает данные, оставшиеся в файл

Мне тоже казалось что это самое вероятное. Только это был пункт 2 :)  А к пункту 1 - тоже НАСТОЯТЕЛЬНО рекомендую присмотрется. Даже если "все работает".

Держать долго открытым файл - не стоит.

Если что-то случится (комп ребутнулся, програ вылетела по ошибке, преравали ее и т.п.) - вы можете потерять все данные. Даже если делали flash. не закрытый файл - это зло. Вообщем лучше открывать его на время записи и закрывать после. 

Обычно файл держат открытым - когда нужно писать много и часто. Для того что-бы не тратить время на открытие/закрытие. Но, так как вы пишите раз в пол часа - тут однозначно нужно закрывать (даже "раз в секунду" - уже будет "редко пишем, поэтому можно и закрыть").

 

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Хм, команду на закрытие знаю close, а на открытие какая? open?

leshak
Offline
Зарегистрирован: 29.09.2011

ingener.solovyev пишет:

Хм, команду на закрытие знаю close, а на открытие какая? open?

Думаю гугл на что-нибудь типа "processing append text file" сможет подсказать. Например:

Processing 1.0 - Processing Discourse - Append to a text file

или Processing 1.0 - Processing Discourse - appending to a text file

ну и доках порытся.

ourlive
Offline
Зарегистрирован: 26.05.2012

 "1. Держать, особенно на таких временных интревалах, файл все время открытм для записи - очень плохая идея :("

лог файл неделями висит открытым, в него регулярно пишется всякая фигня по событиям. За пол года работы был зафиксирован всего один обрыв работы лога, да и то вероятнее всего из-за чьих то шаловливых ручек. При этом этот же лог время от времени открывается для просмотра (обычно браузером, проще увидеть новые записи простым обновлением страницы).