Garage ShoutBox
Tylko zalogowani użytkownicy mogą wejść do czatu
lub Zarejestruj aby założyć posty i tematy.

Rejestrator danych napięcia i prądu

W załączeniu przesyłam skan pliku datalog0.csv po wgraniu ostatniego przesłanego kodu. Zegar pracuje ale zapisuje ciągle (ten sam) czas w którym pomiar się rozpoczął .

Monitor portu szeregowego nie wyświetla żadnej informacji - po włączeniu go restartuje program ale nic się nie pojawia. Próbowałem z różnymi prędkościami ale bez efektu. Może trzeba wysłać jakieś polecenie?

 

Chwila - poczekaj ! Sprawdzę zaraz ostatnią wersję (wysłaną po edit)

Dodane pliki:
  • Aby przesyłać pliki musisz się zalogować.

OK czekam na odpowiedz

Nic się nie zmieniło - zapisuje ciągle ten sam czas! Wygląda na to, że zegar pracuje bo czas się zmienia pomiędzy kolejno wykonywanymi pomiarami - a może tylko w czasie wyłączenia zasilania układu???

Wykonałem próbę polegającą na rejestracji pomiarów przez 3 minuty, zatrzymaniu rejestracji przez 2 minuty i ponownej rejestracji pomiarów przez 3 minut. Zapis z tej próby załączam. Czas się zmienił ale tylko uruchomienia pomiarów - czas trwania pomiarów nie zmienia się!

 

Czy to co napisałem jest zrozumiałe dla Ciebie?

 

Dodane pliki:
  • Aby przesyłać pliki musisz się zalogować.

Dobra to sprobuj to :

Spoiler

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"

RTC_DS1307 rtc;

//Sensors and Switches
int BtnPin = 2, BtnValue = 2, LCDBtnPin = 3; //Switches Pins and Values
int VoltagePin = 0, CurrentPin = 1, LightPin = 2; //Sensor Pins
float Voltage = 0, Current = 0, Power = 0, Light = 0; //Sensor Values
int Clock = 0; //Timer
String MojeDane = "";
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// LCD
#define I2C_ADDR 0x3F // Define I2C Address where the SainSmart LCD is
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C lcd(I2C_ADDR, 2, 1, 0, 4, 5, 6, 7);
String LCDData;

//SD Card
int chipSelect = 10, TestNumber = 0;
String DataString = "", FileName = "";

void setup() {

if (! rtc.begin()) {
Serial.println("Nie moge znalezc zegarka");
Serial.flush();
abort();
}

if (! rtc.isrunning()) {
Serial.println("RTC is NOT running, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

Serial.begin(9600);
//Switches Mode
pinMode(BtnPin, INPUT_PULLUP);
pinMode(LCDBtnPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BtnPin), blink, LOW);
//LCD SETUP
lcd.begin (20, 4);
lcd.setBacklightPin(3, POSITIVE);
lcd.setBacklight(HIGH);
lcd.home();
//SD Card
LCDWrite(0, 0, "Inicjowanie karty SD", 1);
delay(2000);
//Checking if SD Card is inserted
while (!SD.begin(chipSelect))
LCDWrite(0, 0, "Blad karty SD", 1);
//SD card is Inserted
LCDWrite(0, 0, "Karta SD OK!", 1);
delay(2000);
lcd.clear();
}

void loop() {

LCDWrite(0, 0, "System gotowy", 0);
LCDWrite(0, 3, "Wykonaj pomiary", 0);
//Save LCD power by Actuating Red Switch
lcd.setBacklight(!digitalRead(LCDBtnPin));

//Start Measurements When Black Switch is actuated
while (BtnValue == 1) {
//Create a new Excel file Staritng with datalog0
FileName = "datalog" + String(TestNumber) + ".CSV";
File dataFile = SD.open(FileName, FILE_WRITE);
//Save LCD power by Actuating Red Switch
lcd.setBacklight(!digitalRead(LCDBtnPin));
//Record Measurements from Sensors
LCDWrite(0, 0, "REJESTRACJA POMIAROW", 0);
Voltage = analogRead(VoltagePin) / 40.92;
Current = (((analogRead(CurrentPin) * 5.0) / 1023.0) - 2.5) / 0.066;
if (Current < 0)
Current = 0;
Power = Current * Voltage;
Light = 1023 - analogRead(LightPin);
//Start Writing data to File
if (Clock == 0) { //First Line in the Excel Sheet
dataFile.println("Date,Time,Voltage,Current,Power,Light");
dataFile.close();
}

DateTime now = rtc.now();

delay(200);

MojeDane = String (now.year(), DEC);
MojeDane += ".";
MojeDane += String (now.month(), DEC);
MojeDane += ".";
MojeDane += String (now.day(), DEC);
MojeDane += "-";
MojeDane += String (now.hour(), DEC);
MojeDane += ":";
MojeDane += String (now.minute(), DEC);
MojeDane += ":";
MojeDane += String (now.second(), DEC);

DataString = MojeDane + "," + String(Clock) + "," + String(Voltage, 2) + "," + String(Current, 2) + "," + String(Power, 2) + "," + String(Light, 0);
dataFile.println(DataString);//Print Sensor Data to SD Card
dataFile.close();
//Print Data to LCD
LCDData = String(Voltage, 2) + "V, " + String(Current, 2) + "A, " + String(Light, 0) + "L"; //Print Sensor Data to LCD
LCDWrite(0, 1, LCDData, 0);
//Increment time on LCD every 1 minute
LCDWrite(0, 2, "Czas pomiaru:" + String(Clock) + " min", 0);
delay(60000);//Increment 1 minute
Clock = Clock + 1;
if (Clock >= 1)// Stop Measurements after 1 minute if needed
LCDWrite(0, 3, "STOP:" + FileName, 0);
else
LCDWrite(0, 3, " ", 0);
//Stop button actuated at least after 1 minute
if (BtnValue == 0) {
LCDWrite(0, 0, "Zapisano jako:", 1);
TestNumber = TestNumber + 1;//Prepare for a new TestFile
delay(3000);
LCDWrite(0, 1, FileName, 0);
delay(3000);
Clock = 0;//Reset Clock
lcd.clear();
BtnValue = 2;
break;
}
}
}

//Function : Set LCD Cursor Position and Write Message
void LCDWrite(int r, int c, String message, int clearscreen) {
if (clearscreen == 1)
lcd.clear(); //Clear screen if requested
lcd.setCursor ( r, c );
lcd.print(message);
}
//Function : Interrupt and Stop Data Measurements
void blink() {
if (Clock >= 1)
BtnValue = 0;
else
BtnValue = 1;
}

Nie zauwazylem w petli loop petli While.
Tylko raz przebiega caly loop a pozniej juz program jest wykonywany w wewnetrznej petli While.
Teraz umiescilem dopisywanie i odczytywanie czasu wlasnie w tej petli While a nie na poczatku.
Wczesniej program tylko raz odczytywal czas i zapamietywal w zmiennej MojeDane.

TO JEST TO!!!

Popatrz na załącznik - chyba wszystko jest tak jak miało być!

Bardzo dziękuję za fachową pomoc i poświęcony czas. Jestem pod wrażeniem - chciałbym mieć taką wiedzę ale w moim wieku to już raczej niemożliwe.

Jeszcze raz wielkie podziękowanie.

Pozostaję w przeświadczeniu, że w razie pojawienia się jakiś problemów będę mógł się ponownie odezwać.

Dodane pliki:
  • Aby przesyłać pliki musisz się zalogować.

W jakim wieku ? Ja mam 53 lata i jakos ogarniam ...
Mozesz sie nauczyc wszystkiego i to jest kwestia checi.
Mozesz liczyc na pomoc . Prosze.

Zmien sobie jesli chcesz te naglowki w tabeli np na polskie.
Robisz to w linii :
dataFile.println("Date,Time,Voltage,Current,Power,Light");
Przecinki poprostu pozniej okreslaja kolumny.

Niestety ja mam o 16 lat więcej!

Co do nagłówków już sobie wcześniej zmieniłem (robienie spolszczeń w kodzie to akurat ogarniam).

Cieszę się, że w razie potrzeby mogę liczyć na pomoc.

Jeszcze raz bardzo dziękuję.

I znowu jestem!
Sprawdziłem działanie rejestratora pod względem odczytywanych danych (napięcie i prąd). Zbudowałem obwód próbny składając się z źródła zasilania w postaci zasilacza stabilizowanego 5V i obciążenia w formie rezystora 10 ohm/5W. Teoretycznie rejestrator powinien zarejestrować: napięcie 5 V i prąd ok. 0,50 A przez cały czas rejestracji. Niestety tak nie jest! Próbę powtórzyłem z zasilaczem 12 V. Rozumiem lekkie "wahania" odczytów ale różnice, zwłaszcza prądu, dochodzą do ponad 0,2 A (patrz załączone skany)!
Co może być przyczyną takich odczytów? Czy masz jakieś pomysł, który mógłby poprawić odczyt?

W kodzie napięcie i prąd obliczany jest wg:

Voltage = analogRead(VoltagePin) / 41.92;
Current = (((analogRead(CurrentPin) * 5.0) / 1023.0) - 2.5) / 0.066;

Myślę jednak, że problem leży chyba w innym miejscu. Jak często wykonywane jest próbkowanie? Może tu jest jakiś problem?

W załączeniu przesyłam skan schematu połączeń rejesstratora.

Dodane pliki:
  • Aby przesyłać pliki musisz się zalogować.

Glowna przyczyna lezy w elektronice. Niestety AtMega posiada bardzo prosty przetwornik analogowo cyfrowy i mierzy przedewszystkim
napiecie. Pomiar pradu polega na podlaczeniu rezystora o bardzo malej mozliwie rezystancji w szereg i pomiarze spadku napiecia na
tym rezystorze.  Przedewszysrkim trzeba poprawic samo zasilanie ukladu, ale to tylko czesc sukcesu bo jesli nawet ustabilizujesz
napiecie zasilajace to po podlaczeniu ukladu AtMega generuje zmienne obciazenie w takt wykonywania programu co wplywa na
plynacy prad za stabilizatorem a co za tym idzie fluktuacje napiecia. W samej ATMega jest umieszczony uklad odniesienia napiecia do ktorego
przetwornik porownuje napiecie wejsciowe i jesli ono sie waha wlasnia w takt zmieniajacego sie napiecia to sam pomiar i porownanie tez
nie moga byc idealne. Mozna sobie poradzic z tym podlaczajac kilka kondensatorow odsprzegajacych do samego procesora i zewnetrzny uklad
odniesienia napiecia. Dodatkowo ja bym w samym programie usrednial pomiar a dopiero podawal z tego usrednienia wynik. Jednak to taki
sztuczny zabieg. Zeby znaczaco poprawic pomiary trzebaby przebudowac caly uklad pomiarowy. Potraktuj to jako pomiary zgrubne i Arduino
inaczej nie bedzie mierzyc.

Dziękuję za informacje.
Nie wiem czy dobrze zrozumiałem treść Twojej odpowiedzi. Zastanawiam się czy jeśli mówimy (piszemy) o napięciu zasilania to mamy to samo na myśli. Sam rejestrator jako urządzenie jest zasilany napięciem z oddzielnego źródła, innego niż to, które jest mierzone i rejestrowane. Do pomiaru napięcia i prądu wykorzystywane są zewnętrzne czujniki dla Arduino - czujnik napięcia Diymall Dc0-25v oraz czujnik ACS712 - 30A (patrz przesłany w poprzednim poście schemat).
Jak należałoby zmodyfikować kod w celu uśrednienia pomiarów przed podaniem ich wyniku?