Datalogger

Joiner
Offline
Зарегистрирован: 04.09.2014

Прошло уже больше года, как я сделал даталоггер для регистрации каких-либо процессов на SD карту. О нем я писал ранее в теме http://arduino.ru/forum/programmirovanie/razdelit-stroku-na-slova

Там я зачем-то пытался разделить строку на слова......

Joiner
Offline
Зарегистрирован: 04.09.2014

Теперь не помню зачем хотел делить строку, видимо потому, что хотел к даталоггеру еще прилепить дисплей. Но теперь решил, что дисплей тут нафиг не нужен. Он состоит из проминьки, SD модуля и двух светодиодиков, которые сигнализируют о работе устройства, о правильной работе или о проблемах.

Решил выложить здесь, может кому пригодится....а не пригодится, то мне на память :)

Для проверки загрузил одну ардуинку скетчем, который генерирует данные. Подключил ее к даталоггеру и посмотрел, что пишется. 

Суть работы в том, что программа с каким-то периодом формирует строку с данными, и эти данные пишутся на карту. Потом эти данные экспортируются с карты в Excel, и далее анализируются, рисуются красивые графики и прочее

Формат такой

1,235,567,7888

2,67,777,9899

3,99,345,879

Строки нумеруются, поля разделены запятыми. Управляющей программой можно сформировать любые данные.

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

Выглядит это так

А вот сами скетчики

Это для ардуинки которая передает

/*
 * Скетч для передачи в Serial порт какой-нибудь инфы
 * Сделан для испытания Datalogger(а)
 */
long previousMillis=0;//храним время последнего обращения 
long interval=3000;// интервал между обращениями
byte quant_word=5;//Задаем количество слов в строке
void setup() 
{
Serial.begin(9600);//Запускаем Serial порт
}

void loop() 
{
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)//Проверяем интервал, если прошел 
  { 
  previousMillis = currentMillis;//сохраняем время последнего обращения
    //выполняем нужные действия в следующем куске скетча 
    String dataString = "";//Создадим строку для отправки случайных данных данных
    dataString+=String(millis()/interval)+",";//Озаглавливаем(формируем первый столбец)
    //строку секундами или чем еще. Здесь миллисы делим на и интервал, а можно на свой вкус.
        for (int i=0; i <quant_word; i++)
        { 
        dataString+=String(random(0, 1025));//Генерируем случайные числа и прилепляем к строке
        if (i<(quant_word-1)){ dataString+=","; }//Между числами ставим запятую
        }
            Serial.println(dataString);//Записываем в порт что получилось  
  }
}

А это скетчик самого даталоггера


/*
  SD card datalogger для моего модуля
  В модуле Ардуинка про мини и SD модуль. Еще имеется 2 светодиода
  зеленый на пине 9 и красный на пине 8 для индикации работы
  Данный скетч РАБОТАЕТ, сигнализирует, пишет 
 * SD соединяется с SPI шиной следующим образом:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 10
  8.04.16 
 */
#include <SD.h> //Подключаем библиотеку
const byte chipSelect = 10;//Задаем пин CS
byte SdOk=9;//Будет гореть зелененький светик на пине 9 если карта инициализирована
byte Record=8;//Красный светик будет при записи на карту загораться
              //и приследующей записи на карту гаснуть
String dataString = "";//Строка для сохранения поступающих данных
boolean stringComplete = false;//Метка об окончании формирования строки

void setup() 
{
  Serial.begin(9600);//Запускаем Serial порт для отладки программы
  pinMode(SdOk,OUTPUT);//Устанавливаем режим вывода
  pinMode(Record,OUTPUT);//Устанавливаем режим вывода
  pinMode(chipSelect, OUTPUT);//Устанавливаем режим вывода для CS
         //Примечание из примера: "убедитесь, что чип по умолчанию 
         //выберите PIN-кода установлен в положение
         // Выход, даже если вы не используете его"..непонятненько
         //похоже что рекомендуют пин10 в OUTPUT, даже если он не используется
   Serial.print("Initializing SD card...");//Сообщаем, что пытаемся инициализировать SD
   //Смотрим присутствует ли карта и может ли она быть инициализирована
        for (int i=0; i <40; i++)
        { 
             digitalWrite(Record, ! digitalRead(Record));//Сигнализируем, моргаем
             //красным светиком, что пытаемся инициализировать карту  
        delay(50); 
        } 
              if (!SD.begin(chipSelect)) 
              {
                Serial.println("Card failed, or not present");//Пишем, что нет карты
                //дальше ни чего не делаем, если карты нет
                digitalWrite(Record,HIGH);//Извещаем, что карты нет красным светиком
              //return;            
                  while(1)//Карты нет - зависаем здесь
                  { 
                  } 

              }
   Serial.println("card initialized.");//Раз попали сюда, значит карта есть
   digitalWrite(SdOk,HIGH);//Извещаем об этом зеленым светиком
   delay(3000);//Пусть зелененький погорит 3 сек.Б будем знать что с картой все ок
   digitalWrite(SdOk,LOW);//Теперь гасим его, он нам понадобится для других целей
}  


void loop() 
{
  if (Serial.available())
    {
      serialEvent();//Обращаемся к функции считывания порта
    }
  if (stringComplete) 
        {
          //Serial.print(dataString);//Строка для отладки
          SD_Record();//Обращаемся к функции записи на карту
          dataString = "";//Очищаем строку
          stringComplete = false;//Сбрасываем метку
        }
  digitalWrite(SdOk, ! digitalRead(SdOk));//Изображаем работу программы миганием светика
  delay(100);//Здесь задаем частоту опроса порта
  
}

void serialEvent() // Функция считывания порта
{
  while (Serial.available()) 
  {
    
    char inChar = (char)Serial.read();//Считываем байт
    dataString += inChar; //Добавляем к строке
    if (inChar == '\n')//Проверяем на конец строки
    {
      stringComplete = true;//Если конец строки - ставим метку о готовности строки
    }
  }
}



void SD_Record() //Функция записи на карту
{
//Открываем файл. Только один файл может быть открыт. Если открыт какой-то файл
//то его нужно обязательно закрыть.
digitalWrite(Record, ! digitalRead(Record));
File dataFile = SD.open("datalog.txt", FILE_WRITE);//Как понял открываем для записи
    //И если файл доступен, то пишем туда
    if (dataFile) 
      {
    dataFile.print(dataString);//Пишем в файл
    dataFile.close();//Записали, теперь закрываем
      }
      //Если файл не открылся то сообщаем об этом
       else 
          {
          Serial.println("error opening datalog.txt");//Через Serial порт
          for (int i=0; i <41; i++)
                    { 
                    digitalWrite(Record, ! digitalRead(Record));//Красным светиком моргаем,
                    //когда проблема с открытием файла, но если по ходу работы после 
                    //инициализации карты, ее вытащить, то это не срабатывает почему-то
                    delay(20); 
                    } 
          } 
}       


Ну вот....как-то так

 

Штирлиц
Штирлиц аватар
Offline
Зарегистрирован: 13.06.2015

 Немного оффтопа. С года два то-же делал эксперименты с даталоггером и на быструю собрал платку .

Часики , ДС18Б20 ,3 леда для отображения режимов, кнопки...  Самое главное СМД технология.. Вместо смд на этой платке вполне спокойно могли вместится и Атмега в ДИП корпусе , и резисторы МЛТ 5 Ватт...Но для экспериментов это было самое то.

 

Joiner
Offline
Зарегистрирован: 04.09.2014

Штирлиц пишет:

 Немного оффтопа. С года два то-же делал эксперименты с даталоггером и на быструю собрал платку .

.....................................

Ни чего себе "набыструю"! Здесь все по-серьезному.

А я свою делал, кода только-только узнал что такое Arduino. Сейчас бы, конечно, сделал бы совсем по другому, но и эта платка вполне себе универсальная.

Планирую следующий раз применить для изучения поведения аккумуляторов при зарядке-разрядке. Хотя уже делал это и ни чего нового не узнал. Все это давно изучено и расписано.

Joiner
Offline
Зарегистрирован: 04.09.2014

От нечего делать помониторил двое суток температуру на улице и в кавартире. Ипользовал 2 датчика LM75.

Вот что получилось

На синем графике получился резкий зуб вниз, до отрицательной температуры. Это когда я переставлял конструкцию, собранную на макетке, где-то пропал контакт и датчик показал температуру -1.2, поправил, но даталоггер это успел зафиксировать.

Красный график (температура в комнате) прыгающий по тому, что это реакция на открытие и закрытие окна.

На очереди...ну, короче поиграю с аккумуляторами.

Joiner
Offline
Зарегистрирован: 04.09.2014

Промониторил еще раз температуру внутри квартиры и на улице. На этот раз сделал не просто временные промежутки, а конкретно обозначил время записи результата измерения. "Часами" работали миллисы программы. Пришлось написать функцию часов. За сутки эти часики ушли больше чем на минуту, но в данном случае это не имеет ни какого значения. Вот что получилось. Небольшой косячек в том, что температура измерялась не в 8:10:00, а получилось 8:08:57....немного коряво. Исправлю.

Не думал, что такие колебания температуры получатся....предполагал что линии плавные получатся.

valera140582
Offline
Зарегистрирован: 01.07.2016

Здравствуйте! Меня заинтересовала ваша  плата в сообщении #2 . Можно взглянуть на исходник?

Штирлиц
Штирлиц аватар
Offline
Зарегистрирован: 13.06.2015

valera140582 пишет:

Здравствуйте! Меня заинтересовала ваша  плата в сообщении #2 . Можно взглянуть на исходник?

Да без проблем . Держите. Но предупреждаю- делалось все на скорую руку и из того , что было под рукой . Фактически - первая проба работы с СМД. Так что лучше передалайте под свои реалии .Делалось в DipTrace, одностороняя плата , ЛУТ.

Цель была - поработать с ДАТАЛОГГЕРОМ, а не создание "правильной" платы.