|
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
marko11 Član
Pridružen-a: Ned 14 Dec 2003 17:47 Prispevkov: 866 Aktiv.: 3.88 Kraj: Dobrepolje
|
Objavljeno: Pet Okt 14, 2022 4:30 pm Naslov sporočila: Arduino zapis na micro SD kartico |
|
|
Hi
Nikakor ne morem zapisati podatkov na SDmicro kartico.
Ko naložim na arduino nano spodnji program, na kartici ustvari "arduino.txt" datoteko.
Koda: |
/*
* Created by ArduinoGetStarted.com
*
* This example code is in the public domain
*
* Tutorial page: https://arduinogetstarted.com/tutorials/arduino-micro-sd-card
*/
#include <SD.h>
#define PIN_SPI_CS 4
File myFile;
void setup() {
Serial.begin(9600);
if (!SD.begin(PIN_SPI_CS)) {
Serial.println(F("SD CARD FAILED, OR NOT PRESENT!"));
while (1); // don't do anything more:
}
Serial.println(F("SD CARD INITIALIZED."));
if (!SD.exists("arduino.txt")) {
Serial.println(F("arduino.txt doesn't exist. Creating arduino.txt file..."));
// create a new file by opening a new file and immediately close it
myFile = SD.open("arduino.txt", FILE_WRITE);
myFile.close();
}
// recheck if file is created or not
if (SD.exists("arduino.txt"))
Serial.println(F("arduino.txt exists on SD Card."));
else
Serial.println(F("arduino.txt doesn't exist on SD Card."));
}
void loop() {
}
|
Ko pa naložim spodnji program, da zapisuje podatke na kartico, pa javi napako, na serial portu izpiše "initialization failed!"
Kje bi lahko bil problem? SD kartica je 2GB
Koda: |
#include <SPI.h>
#include <SD.h>
File myFile;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(10)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("arduino.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("This is a test file :)");
myFile.println("testing 1, 2, 3.");
for (int i = 0; i < 20; i++) {
myFile.println(i);
}
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop() {
// nothing happens after setup
}
|
LP, marko |
|
Nazaj na vrh |
|
|
frenki Moderator
Pridružen-a: Ned 23 Feb 2003 21:26 Prispevkov: 6556 Aktiv.: 29.39 Kraj: Ljubljana (JN76GB)
|
Objavljeno: Pet Okt 14, 2022 4:42 pm Naslov sporočila: |
|
|
Prvi listing:
Koda: |
#define PIN_SPI_CS 4
.
.
.
if (!SD.begin(PIN_SPI_CS)) { |
Drugi listing:
Koda: |
if (!SD.begin(10)) { |
|
|
Nazaj na vrh |
|
|
eddie Član
Pridružen-a: Sre 10 Dec 2003 21:02 Prispevkov: 706 Aktiv.: 3.16 Kraj: Severna primorska
|
Objavljeno: Pet Okt 14, 2022 4:42 pm Naslov sporočila: |
|
|
"SD.begin(10)" je drugače kot v prvem primeru.
Če prvi primer deluje potem mora biti v oklepaju številka 4.
Lp |
|
Nazaj na vrh |
|
|
marko11 Član
Pridružen-a: Ned 14 Dec 2003 17:47 Prispevkov: 866 Aktiv.: 3.88 Kraj: Dobrepolje
|
Objavljeno: Sob Okt 15, 2022 5:19 pm Naslov sporočila: |
|
|
Hi
Na Arduino Nano mora biti pin kartice CS, povezan na D10.
Sedaj deluje. Hvala.
Še eno vprašanje:
Imam 32GB micro kartico, pa me zanima če podpira tudi to velikost?
LP,marko |
|
Nazaj na vrh |
|
|
mato1111 Član
Pridružen-a: Pet 28 Dec 2012 14:42 Prispevkov: 612 Aktiv.: 4.44 Kraj: Vrhnika
|
Objavljeno: Sob Okt 15, 2022 6:11 pm Naslov sporočila: |
|
|
V knjižnici piše da podpira SD (do 2GB) in SDHC (2-32GB).
Moraš pa pazit tudi na format imena datotek, ki je max 8.3 npr. datoteka.txt |
|
Nazaj na vrh |
|
|
marko11 Član
Pridružen-a: Ned 14 Dec 2003 17:47 Prispevkov: 866 Aktiv.: 3.88 Kraj: Dobrepolje
|
Objavljeno: Ned Okt 16, 2022 1:54 pm Naslov sporočila: |
|
|
Problemi, problemi......
Problemi z zapisovanjem na SD kartico.
Ko zaženem spodnji program, se začne zapisovati na SD in to nekako zapiše 10 do 12 zapisov in potem je konec zapisovanja.
Ugotovil sem, ko odstranim rutino za prekinitev pa program pravilno deluje in nonstop zapisuje podatke.
Torej, je nepravilno zapisana ta rutina, ki povzroča problem. Se mi pa sploh ne sanja kako napisati drugače, tako da bo ko pride impulz ki sproži prekinitev, da zapiše podatek na SD in potem nadaljuje z pisanjem temperatur na Sd.
Prosim za nasvet kako to spisati da bo to delovalo.
Najlepša hvala in LP,marko
Koda: |
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <SD.h>
#define PIN_SPI_CS 10 //pin D10 na arduino NANO
//SD CARD NANO
//-------------------
//Miso D12
//CLK D13
//Mosi D11
//CS D10
#include <DS1307.h>
DS1307 clock; //(0x68)
RTCDateTime dt;
File myfile;
/********************************************************************/
#define ONE_WIRE_BUS_1 8 // Pin D8 zunaj
#define ONE_WIRE_BUS_2 9 // Pin D9 peč
OneWire oneWire_zunaj(ONE_WIRE_BUS_1);
OneWire oneWire_pec(ONE_WIRE_BUS_2);
DallasTemperature sensors_zunaj(&oneWire_zunaj);
DallasTemperature sensors_pec(&oneWire_pec);
/********************************************************************/
int x = 0;
float a = 0.0000; //začetno stanje
float b = 0.0025; //prištevanec
//===========================================================================
void setup() {
attachInterrupt(0, ISR_meritev, RISING); // PREKINITEV Rising prehod iz LOW na High
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
Serial.println("Inicializiraj DS1307");
sensors_zunaj.begin();
sensors_zunaj.setResolution (0, 10);
sensors_pec.begin();
sensors_pec.setResolution (0, 10);
clock.begin();
if (!clock.isReady())
{
// Nastavite čas
// clock.setDateTime(__DATE__, __TIME__);
// Rocno vnasanje (YYYY, MM, DD, HH, mm, SS
//clock.setDateTime(2022, 4, 18, 12, 53, 00);
}
if (!SD.begin(10)) {
Serial.println("initialization failed!");
return;
}
myfile = SD.open("arduino.txt", FILE_WRITE);
}
//====================================================
void loop() {
sensors_zunaj.requestTemperatures ();
float t1 = sensors_zunaj.getTempCByIndex (0);
Serial.println (t1);
sensors_pec.requestTemperatures ();
float t2 = sensors_pec.getTempCByIndex (0);
Serial.println (t2);
dt = clock.getDateTime();
// Napiši na serijski vmesnik Datum in uro
Serial.print("Datum in ura: ");
Serial.print(dt.year); Serial.print("-");
Serial.print(dt.month); Serial.print("-");
Serial.print(dt.day); Serial.print(" ");
Serial.print(dt.hour); Serial.print(":");
Serial.print(dt.minute); Serial.print(":");
Serial.print(dt.second); Serial.println("");
myfile = SD.open("arduino.txt", FILE_WRITE);
if(myfile){
myfile.print(dt.day); myfile.print("-");
myfile.print(dt.month); myfile.print("-");
myfile.print(dt.year); myfile.print("; ");
myfile.print(dt.hour); myfile.print(":");
myfile.print(dt.minute); myfile.print(":");
myfile.print(dt.second); myfile.print("; ");
myfile.print("T.zunaj: ");
myfile.print(t1);
myfile.print("; ");
myfile.print("T.soba: ");
myfile.print(t2);
myfile.println("; ");
myfile.close();
}
delay (2000); //počakaj 2 sek. in ponovno zapiši na SD
}
//=========================================================================
void ISR_meritev() { // prekinitev
// Ko pride impulz na D2 se sproži prekinitev. Preračuna a,b ter podatke z datumom
// vpiši na SD kartico. Potem pa se vrni in zapisuj temperaturo na SD kartico
a = a + b;
Serial.println("Novo stanje kWh ");
Serial.print (a,4); // 4 pomeni da izpiše 4 decimalke
Serial.println();
myfile = SD.open("arduino.txt", FILE_WRITE);
if(myfile){
myfile.print(dt.day); myfile.print("-");
myfile.print(dt.month); myfile.print("-");
myfile.print(dt.year); myfile.print("; ");
myfile.print(dt.hour); myfile.print(":");
myfile.print(dt.minute); myfile.print(":");
myfile.print(dt.second); myfile.print("; ");
myfile.print(" kWh: ");
myfile.print(a,4);
myfile.print(";");
myfile.println();
myfile.close();
}
}
|
|
|
Nazaj na vrh |
|
|
mato1111 Član
Pridružen-a: Pet 28 Dec 2012 14:42 Prispevkov: 612 Aktiv.: 4.44 Kraj: Vrhnika
|
Objavljeno: Pon Okt 17, 2022 8:33 am Naslov sporočila: |
|
|
Najbrš se zgodi situacija, ko v zanki zapisuješ na kartico, vmes pa se zgodi prekinitev, ki tudi hoče pisat na kartico...
Omejitev je tudi da imaš lahko odprto samo eno datoteko iz SD kartice naenkrat.
Probaj v prekinitvi dati neko "zastavico", ki jo boš preverjal v loop zanki kadar ne boš zapisoval temperature. Seveda brez delay() v loop - uporabljaj operacije z millis() Poglej si tu
Prekinitev naj bi bila čim krajša tako, da vse kar ni zelo nujno lahko preseliš v loop npr. pisanje na serial itd. pomagaš si z "zastavico"
PS: če ti slučajno ni jasno zastavica je neka spremenljivka, ki ji spreminjaš vrednost recimo 0 in 1. |
|
Nazaj na vrh |
|
|
marko11 Član
Pridružen-a: Ned 14 Dec 2003 17:47 Prispevkov: 866 Aktiv.: 3.88 Kraj: Dobrepolje
|
Objavljeno: Sre Okt 26, 2022 7:58 pm Naslov sporočila: |
|
|
Hi
Ne vem zakaj se prekine po kakih 10-ih urah, zapisovanje na SD kartico.
To se vedno dogaja, ko pustim zapisovanje dalj časa.
Ali je mogoče vzrok kje v spodnji kodi?
Koda: |
void setupTimer1() {
noInterrupts();
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
// 1 Hz (16000000/((15624+1)*1024))
OCR1A = 15624; // to je izračun za ENO sekundo
// CTC
TCCR1B |= (1 << WGM12);
// Prescaler 1024
TCCR1B |= (1 << CS12) | (1 << CS10);
// Output Compare Match A Interrupt Enable
TIMSK1 |= (1 << OCIE1A);
interrupts();
}
// --------------------- konec setupTimer1 funkcije -------------
void setup() {
attachInterrupt(0, ISR_meritev, RISING); // Rising prehod iz LOW na High
setupTimer1(); // pokliči timer
//Zastavica = 0;
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
if (!SD.begin(10)) {
Serial.println("initialization failed!");
return;
}
//--------------------------------------------- DS1307
Serial.println("Inicializiraj DS1307");;
clock.begin();
// Rocno vnasanje (YYYY, MM, DD, HH, mm, SS
//clock.setDateTime(2022, 10, 9, 18, 3, 00); // ko spreminjaš čas odkomentiraj stavek in vpiši novi čas
// Če datum ni določen
if (!clock.isReady()) {
// Nastavite čas prevajanja skic
// clock.setDateTime(__DATE__, __TIME__);
// Rocno vnasanje (YYYY, MM, DD, HH, mm, SS
//clock.setDateTime(2014, 4, 18, 12, 53, 00);
}
//-----------------------------------------------------
sensors_zunaj.begin();
sensors_zunaj.setResolution (0, 10); //in here it ends the temperature reading/writing
}
// --------------------------- ISR TIMER1 funkcija ------------------------------------
ISR(TIMER1_COMPA_vect) {
stevec_1++;
if(stevec_1 > 300) // štej do 300, to je 5 minut
stevec_1 = 0;
}
// -------------------------- konec funkcije ISR TIMER ---------------------------
void loop() {
if ((stevec_1 == 300) && (Zastavica == 0)){
stevec_1 = 0;
sensors_zunaj.requestTemperatures ();
float t1 = sensors_zunaj.getTempCByIndex (0);
Serial.println (t1);
Serial.println(x, DEC); //print x to serial monitor
dt = clock.getDateTime();
Serial.print("Datum in ura: ");
Serial.print(dt.year); Serial.print("-");
Serial.print(dt.month); Serial.print("-");
Serial.print(dt.day); Serial.print(" ");
Serial.print(dt.hour); Serial.print(":");
Serial.print(dt.minute); Serial.print(":");
Serial.print(dt.second); Serial.println("");
Serial.println(a,4); // napiši izračunano vrednost a ob prekinitvi
myfile = SD.open("arduino.txt", FILE_WRITE);
if(myfile){ // izpisi na SD kartico
myfile.print(dt.day); myfile.print(".");
myfile.print(dt.month); myfile.print(".");
myfile.print(dt.year); myfile.print("; ");
myfile.print(dt.hour); myfile.print(":");
myfile.print(dt.minute); myfile.print(":");
myfile.print(dt.second); myfile.print("; ");
myfile.print(a,4);
//myfile.print("T.zunaj: ");
myfile.println(t1);
myfile.close();
}
}
}
// ============================================
void ISR_meritev() { //ISR prekinitev
Zastavica = 1;
x++;
a = a + b;
Zastavica = 0;
}
|
|
|
Nazaj na vrh |
|
|
mateik Član
Pridružen-a: Sob 06 Avg 2022 18:31 Prispevkov: 148 Aktiv.: 7.03 Kraj: Ljubljana
|
Objavljeno: Sre Okt 26, 2022 9:11 pm Naslov sporočila: |
|
|
Čemu služi tole?
Citiram: |
// --------------------------- ISR TIMER1 funkcija ------------------------------------
ISR(TIMER1_COMPA_vect) {
stevec_1++;
if(stevec_1 > 300){ // štej do 300, to je 5 minut
stevec_1 = 0;
}
}
// -------------------------- konec funkcije ISR TIMER ---------------------------
} |
Manjka verjetno { } za IF? Pa pa če je štetje bi bilo mogoče boljše FOR zanka, ampak zakaj ni to v loopu?
In kje je definiran stevec_1 ?
Mogoče ga postavi v volatile
Lahko bi še popravil
Citiram: |
attachInterrupt(0, ISR_meritev, RISING); // Rising prehod iz LOW na High |
attachInterrupt(digitalPinToInterrupt(0), ISR_meritev. RISING); |
|
Nazaj na vrh |
|
|
bostjang Član
Pridružen-a: Tor 03 Jan 2006 15:29 Prispevkov: 3175 Aktiv.: 14.24 Kraj: Postojna
|
Objavljeno: Čet Okt 27, 2022 9:48 am Naslov sporočila: |
|
|
Dajanje enega stavka v zavite oklepaje (blok) ne spremeni izvajanja kode. |
|
Nazaj na vrh |
|
|
mato1111 Član
Pridružen-a: Pet 28 Dec 2012 14:42 Prispevkov: 612 Aktiv.: 4.44 Kraj: Vrhnika
|
Objavljeno: Čet Okt 27, 2022 8:49 pm Naslov sporočila: |
|
|
Vrednost spremenljivke a spreminjas v prekinitvi in zapisujes na kartico. Lahko se zgodi da se sprozi prekinitev in spremeni podatek ravno ko ga zapisujes na kartico kar ni ravno dobro
mateik je napisal/a: |
Čemu služi tole?
Citiram: |
// --------------------------- ISR TIMER1 funkcija ------------------------------------
ISR(TIMER1_COMPA_vect) {
stevec_1++;
if(stevec_1 > 300){ // štej do 300, to je 5 minut
stevec_1 = 0;
}
}
// -------------------------- konec funkcije ISR TIMER ---------------------------
|
|
To je prekinitvena rutina, ki povecuje nek stevec vsako sekundo. V zanki potem preverja kdaj mine 300s (5min) in naredi meritev in zapisa na kartico. To je uporabil namesto delay() da ne blokira izvajanja zanke.
To bi enostavno resil z uporabo millis(), primer spodaj
Koda: |
int period1 = 5000; //Milisekunde
int period2 = 10000; //Milisekunde
unsigned long time1 = millis(); //Zapomni si trenutni cas (potrebno cakat eno periodo za prvo izvajanje v zanki)
unsigned long time2 = millis()-period2; //Zapomni si trenutni cas - peroda (ni potrebno cakat ene periode za prvo izvajanje v zanki)
void setup() {
Serial.begin(9600);
delay(500);
Serial.println("Start");
}
void loop() {
if((millis() - time1) >= period1){ //Razlika med trenutnim in zadnjim prebranim casom mora bit >= od periode
time1 = millis(); //Zapomni si trenutni cas
Serial.println("Hello1");
// Vsebina znotraj tega if stavka se izvede vsakih 5 s
}
if(millis() - time2) >= period2){ //Razlika med trenutnim in zadnjim prebranim casom mora bit >= od periode
time2 = millis(); //Dobi trenutni cas
Serial.println("Hello2");
// Vsebina znotraj tega if stavka se izvede vsakih 10 s
}
}
|
Nazadnje urejal/a mato1111 Ned Okt 30, 2022 7:41 pm; skupaj popravljeno 1 krat |
|
Nazaj na vrh |
|
|
marko11 Član
Pridružen-a: Ned 14 Dec 2003 17:47 Prispevkov: 866 Aktiv.: 3.88 Kraj: Dobrepolje
|
Objavljeno: Čet Okt 27, 2022 9:35 pm Naslov sporočila: |
|
|
Kje naj bi bila razlika med uporabo timerja in uporabo millis ?
Ker meni ta millis ni čisto jasen.
Lp, |
|
Nazaj na vrh |
|
|
mato1111 Član
Pridružen-a: Pet 28 Dec 2012 14:42 Prispevkov: 612 Aktiv.: 4.44 Kraj: Vrhnika
|
Objavljeno: Ned Okt 30, 2022 7:37 pm Naslov sporočila: |
|
|
"Zadaj" je nek stevec, ki poveca vrednost vsako 1 milisekundo.
Vrednost preberes z klicem millis(), potem samo primerjas razliko mes zadnjo vrednostjo ko si klical millis in trenutno vrednostjo millis. |
|
Nazaj na vrh |
|
|
marko11 Član
Pridružen-a: Ned 14 Dec 2003 17:47 Prispevkov: 866 Aktiv.: 3.88 Kraj: Dobrepolje
|
Objavljeno: Ned Nov 06, 2022 5:49 pm Naslov sporočila: |
|
|
Hi
Sedaj imam program napisan malo drugače, tako da uporabim zastavico, kot je predlagal mato1111, pa se še vedno dogaja to, da se kar naenkrat čez toliko ur, predvidevam, program "zresetira" in začne od začetka. Podatki se zapisujejo v 15 minutnih presledkih.
Tu je del popravljenega programa:
Koda: |
ISR(TIMER1_COMPA_vect) {
stevec_1++;
}
void loop() {
if ((stevec_1 == 900) && (Zastavica == 0)){ // 900 = 15 min
stevec_1 = 0;
sensors_zunaj.requestTemperatures ();
float t1 = sensors_zunaj.getTempCByIndex (0);
Serial.println (t1);
Serial.println(x, DEC); //print x to serial monitor
dt = clock.getDateTime();
Serial.print("Datum in ura: ");
Serial.print(dt.year); Serial.print("-");
Serial.print(dt.month); Serial.print("-");
Serial.print(dt.day); Serial.print(" ");
Serial.print(dt.hour); Serial.print(":");
Serial.print(dt.minute); Serial.print(",");
Serial.print(dt.second); Serial.println("");
Serial.println(kWh,4); // napiši izračunano vrednost kWh ob prekinitvi
Serial.println("");
myfile = SD.open("arduino.txt", FILE_WRITE);
if(myfile){ // izpisi na SD kartico
myfile.print(dt.day); myfile.print(".");
myfile.print(dt.month); myfile.print(".");
myfile.print(dt.year); myfile.print("; ");
myfile.print(dt.hour); myfile.print(":");
myfile.print(dt.minute); myfile.print(",");
myfile.print(dt.second); myfile.print("; ");
myfile.print(kWh,4);
myfile.print("; ");
myfile.println(t1);
myfile.close();
}
}
}
void ISR_meritev() {
Zastavica = 1;
x++;
kWh = kWh + Pulz;
Zastavica = 0;
}
|
Tu pa je primer kako zapisuje na SD kartico:
Koda: |
5.11.2022; 10:2,18; 8.3126; 8.94
5.11.2022; 10:17,18; 8.3951; 9.38
5.11.2022; 10:32,18; 8.4076; 9.69
Tukaj se nekaj zgodi, kot, da se procesor resetira
in da začne program od začetka.
5.11.2022; 11:0,28; 0.0175; 11.13
5.11.2022; 11:15,27; 0.1200; 10.88
5.11.2022; 11:30,27; 0.4100; 11.00
5.11.2022; 11:45,27; 0.6300; 10.63
5.11.2022; 12:0,27; 0.7475; 10.56
|
Sploh mi ni jasno zakaj pride do te prekinitve. Uporabljam modul Arduino Nano.
Mogoče kdo od vas pozna vzrok zakaj pride do te napake.
Za kakršen koli nasvet se vam zahvaljujem.
LP, marko |
|
Nazaj na vrh |
|
|
eddie Član
Pridružen-a: Sre 10 Dec 2003 21:02 Prispevkov: 706 Aktiv.: 3.16 Kraj: Severna primorska
|
Objavljeno: Ned Nov 06, 2022 8:49 pm Naslov sporočila: |
|
|
Z napajanjem je vse uredu? |
|
Nazaj na vrh |
|
|
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 79 dni
Powered by phpBB © 2001, 2005 phpBB Group
|