wtorek, 22 września 2015

[II] Arduino - Projekt - Czterokanałowy termometr z prezentacją danych

Tym razem postanowiłem trochę polepszyć ostatnio prezentowany przeze mnie projekt na arduino. Do całości procesu dodałem dwa czujniki temperatury, jeden DS18B20 (w sumie będzie ich już trzy) oraz LM35 (analogowy czujnik temperatury).

Przygotowałem dwa programy jeden działający z na wyświetlaczu HD44780 2x16, natomiast drugi prezentuje dane poprzez port szeregowy.

Podłączenie

Podłączenie jest takie samo jak w przypadku poprzedniego projektu. Dodane czujniki zostały podłączone:

DS18B20:
  • VCC - Pin Arduino 5V;
  • DQ - Pin Arduino 2;
  • GND - Pin Arduino GND;

LM35:
  • VCC - Pin Arduino 5V;
  • Dane - Pin Arduino A0;
  • GND - Pin Arduino GND;
SD Card
  •     GND  - Pin Arduino GND
  •     MISO - Pin Arduino 12
  •     SCK  - Pin Arduino 13
  •     MOSI - Pin Arduino 11
  •     SDCS - Pin Arduino 10 SS
  •     5V   - 5V  
  •     3.3V - NC
  •     GND  - NC

Program 1

W tym przypadku zaprezentuje program do wyświetlania danych na wyświetlaczu oraz zapisu przetworzonych danych do pliku.

Potrzebne były niewielkie zmiany w porównaniu z programem przedstawionym w projekcie I. Głównie należało odpowiednio dobrać wyświetlanie danych i ich zapis do pliku. Spowodowane jest to tym, że czujniki DS18B20 mogą być w dużej ilości podłączone pod jeden pin arduino. Czujniki wyszukiwane są po ich adresie.

#include <SD.h>
#include <SPI.h>
#include <OneWire.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
 
//Linia danych podpięta jest pod pin 2 Ardiuno
#define ONE_WIRE_BUS 2           
const int LM35Pin = 0;
 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
OneWire oneWire(ONE_WIRE_BUS);
//Nazwa pliku
File myFile;                          
 
//Przekazanie danych dotyczących One Wire do DallasTemperature
DallasTemperature sensors(&oneWire);  
 
float temp;
float OdczytTemp = 0;
 
void setup()
{
  //Inicjalizacja wyświetlacza, ilość kolumn (16), ilość wierszy (2)
  lcd.begin(16,2);
  //Włączenie podświetlania
  lcd.backlight();
  //Ustawienie kursora w pozycji 0,0
  lcd.setCursor(0,0);
  //Wyświetlenie stringa na wy
  lcd.print("Inicjalizacja karty SD"); 
  //Nawet jeśli jest nie używany to pin SS (10 Arduino Uno) 
  //musi być zostawiony jako wyjście  
  pinMode(10, OUTPUT); 
 
  delay(200);
  lcd.clear();
  //Sprawdzanie czy inicjalizacja została zrobiona, 
  //jeśli nie to wyświetl dane w pętli  
  if (!SD.begin(10))                                                      
  {                        
    lcd.setCursor(0,0);                   
    lcd.print("Inic. nieudana");
    //Wróć na początek programu
    return;                           
  }
 
  lcd.print("Inic. poprawna");            
  delay(1000);
  lcd.clear();
 
  //Otwórz plik, tylko jedne plik może być otwarty w danym momencie
  //trzeba zamknąć każdy otwarty przed otwarciem następnego
  myFile = SD.open("test.txt", FILE_WRITE);                
 
  //Jeśli plik się otworzył to zapisz do niego następujące dane
  if (myFile)   
  {
    //Wpisz stringa do pliku 
    myFile.println("Wykaz temperatury czujnikow DS18B20");
    //Zamknięcie pliku
    myFile.close();                                         //Zamknięcie pliku
    //Serial.println(" Dane wpisane");
  } 
  else 
  {
    lcd.setCursor(0,0);
    lcd.print("Blad otwarcia pliku");
    //Serial.println("Blad otwarcia pliku test.txt");       //Jeśli plik się nie otworzy wyświetl błąd:
  }
  delay(300);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temp wynosi: ");
  sensors.begin();
  delay(1000);
  lcd.clear();
}
 
void loop()
{
  float T1, T2, T3;
  static int a=0;
  sensors.requestTemperatures();                 //Wysłanie komendy do pobrania temperatury
 
  T1 = sensors.getTempCByIndex(0);
  T2 = sensors.getTempCByIndex(1);
  T3 = sensors.getTempCByIndex(2);
 
  lcd.setCursor(0,0);
  lcd.print("1:");
  lcd.setCursor(2,0);
  lcd.print(T1);
  lcd.setCursor(8,0);
  lcd.print("2:");
  lcd.setCursor(10,0);
  lcd.print(T2);
  lcd.setCursor(0,1);
  lcd.print("3:");
  lcd.setCursor(2,1);
  lcd.print(T3);
  lcd.setCursor(8,1);
  lcd.print("4:");
  temp = analogRead(LM35Pin);
  OdczytTemp = (5.0 * temp * 100.0)/1024; 
  lcd.setCursor(10,1);
  lcd.print(OdczytTemp);
 
  delay(300);
  //Następuje otwarcie pliku o zadanej nazwie,
  //z zainicjalizowaną funckją zapisu
 
  myFile = SD.open("test.txt", FILE_WRITE); 
 
  //Jeśli plik się otworzył to zapisz do niego następujące dane
  if (myFile)                              
  {
    myFile.print(a); 
    myFile.print(" : Temp 1: ");
    myFile.print(T1);
    myFile.print(" st. C");
    myFile.print(" Temp 2: ");
    myFile.print(T2);
    myFile.print(" st. C");
    myFile.print(" Temp 3: ");
    myFile.print(T2);
    myFile.print(" st. C");
    myFile.print(" Temp 4: ");
    myFile.print(T2);
    myFile.println(" st. C");
    //Zamknięcie pliku
    myFile.close();
  } 
  else 
  {
    lcd.setCursor(14,1);
    //Jeśli plik się nie otworzy wyświetl błąd:
    lcd.print("B");              
  }
  delay(800);
}

Rys. 1.1. Prezentacja danych

Program 2

W tym przypadku zaprezentuje program do wyświetlania danych poprzez port szeregowy oraz zapisu przetworzonych danych do pliku.

I tym razem program nie uległ zbytniej zmianie. Sposób wyświetlania danych na wyświetlaczu został zastąpiony przez port szeregowy. I to właściwie tyle.

#include <SD.h>
#include <SPI.h>
#include <OneWire.h>
#include <Wire.h>
#include <DallasTemperature.h>
 
//Linia danych podpięta jest pod pin 2 Ardiuno
#define ONE_WIRE_BUS 2           
const int LM35Pin = 0;
 
OneWire oneWire(ONE_WIRE_BUS);
//Nazwa pliku
File myFile;                          
 
//Przekazanie danych dotyczących One Wire do DallasTemperature
DallasTemperature sensors(&oneWire);  
 
float temp;
float OdczytTemp = 0;
 
void setup()
{
  Serial.begin(9600);
  Serial.println("Inicjalizacja karty SD"); 
 
  pinMode(10, OUTPUT); 
 
  //Sprawdzanie czy inicjalizacja została zrobiona, 
  //jeśli nie to wyświetl dane w pętli  
  if (!SD.begin(10))                                                      
  {                                         
    Serial.println("Inicjalizacja nieudana");
    //Wróć na początek programu
    return;                           
  }
 
  Serial.println("Inicjalizacja poprawna");            
 
  //Otwórz plik, tylko jedne plik może być otwarty w danym momencie
  //trzeba zamknąć każdy otwarty przed otwarciem następnego
  myFile = SD.open("test.txt", FILE_WRITE);                
 
  //Jeśli plik się otworzył to zapisz do niego następujące dane
  if (myFile)   
  {
    //Wpisz stringa do pliku 
    myFile.println("Wykaz temperatury czujnikow DS18B20");
    //Zamknięcie pliku
    myFile.close();                                         
    //Serial.println(" Dane wpisane");
  } 
  else 
  {
    //Jeśli plik się nie otworzy wyświetl błąd:
    Serial.println("Blad otwarcia pliku test.txt");    
  }
  Serial.println("Odczytana temperatura wynosi: ");
  sensors.begin();
}
 
void loop()
{
  float T1, T2, T3;
  static int a=0;
  //Wysłanie komendy do pobrania temperatury
  sensors.requestTemperatures();      
 
  T1 = sensors.getTempCByIndex(0);
  T2 = sensors.getTempCByIndex(1);
  T3 = sensors.getTempCByIndex(2);
 
  Serial.print("Czujnik 1: ");
  Serial.print(T1);
  Serial.print(" st. C ");
  Serial.print(" Czujnik 2: ");
  Serial.print(T2);
  Serial.print(" st. C ");
  Serial.print(" Czujnik 3: ");
  Serial.print(T3);
  Serial.print(" st. C ");
  Serial.print(" Czujnik 4: ");
  temp = analogRead(LM35Pin);
  OdczytTemp = (5.0 * temp * 100.0)/1024; 
  Serial.print(OdczytTemp);
  Serial.println(" st. C ");
 
  //Następuje otwarcie pliku o zadanej nazwie,
  //z zainicjalizowaną funckją zapisu
 
  myFile = SD.open("test.txt", FILE_WRITE); 
 
  //Jeśli plik się otworzył to zapisz do niego następujące dane
  if (myFile)                              
  {
    myFile.print(a); 
    myFile.print(" : Temp 1: ");
    myFile.print(T1);
    myFile.print(" st. C");
    myFile.print(" Temp 2: ");
    myFile.print(T2);
    myFile.print(" st. C");
    myFile.print(" Temp 3: ");
    myFile.print(T2);
    myFile.print(" st. C");
    myFile.print(" Temp 4: ");
    myFile.print(T2);
    myFile.println(" st. C");
    //Zamknięcie pliku
    myFile.close();
  } 
  else 
  {
    Serial.print("Błąd otwarcia pliku");           
  }
  delay(1000);
}


Rys. 1.2. Prezentacja danych - port szeregowy