Salve a tutti, qualche mese fa o comprato un arduino pro mini (Con Atmega168), siccome ho realizzato un sistema standalone per la gestione del giardino, ho deciso di usare un modulo bluetooth per controllare il tutto a distanza senza scomodarmi troppo. tutto funziona correttamente, ma la seriale dopo diverse Letture/scritture comincia a dare problemi nella scrittura delle informazioni. visto che comunque sono "computer" molto scarni ho deciso di rendere scarno anche l'output, ma purtroppo se non resetto dopo un tot il sistema il problema persiste. Resettare il sistema è un problema perchè uso la libreria "SWRtc" che mi permette di temporizzare qualunque cosa. Dove potrebbe essere il problema? il problema si verifica anche quando il micro è collegato alla board arduino uno senza micro. Come posso procedere? Ho usato diverse volte la seriale, ma non mi ha mai creato questi problemi... Grazie
Penso che hai un problema di RAM.
Ciao Uwe
Come posso risolvere? io uso massimo una decina di variabili (char), le librerie non le ho scritte io
Il atmega168 è simile al solito atmega328 ma ha la metà della SRAM (1 solo Kb) che già sul 328 è poca (2Kb).
Penso che l'hai comprato a poco (non è più in produzione come prodotto ufficiale) quindi non dovrebbe essere difficile comprarne uno sempre a poco ma con il 328
La versione con Atmega168 della ProMini, ha solo 1KByte di RAM ( la meta dell'Atmega328 ), quindi a saturarla ci vuole veramente poco.
Posta lo sketch, vediamo se è migliorabile
GalaxyHD96:
Come posso risolvere? io uso massimo una decina di variabili (char), le librerie non le ho scritte io
Ma userai un sacco di Serial.print() che mangiano anche loro della RAM.
Ciao Uwe
il codice é nell'altro pc, ma non esiste una funzione per liberare la memoria?
GalaxyHD96:
il codice é nell'altro pc, ma non esiste una funzione per liberare la memoria?
No. Arduino non è un pc. Usa una MCU senza sistema operativo.
nono, dico che il codice che ho scritto è messo nell'altro computer... lo so che non è un pc arduino...
La risposta era riferita alla seconda parte della frase, alla domanda sul sistema per liberare la memoria, che esiste nei PC.
GalaxyHD96:
nono, dico che il codice che ho scritto è messo nell'altro computer... lo so che non è un pc arduino...
Ma che vuol dire liberare memoria sul PC ? Un PC con 3-4Gb minimo oramai, con un sistema operativo che già fa pulizia della memoria e/o un linguaggio tipo Java che ha la sua pulizia (garbage collection) che senso ha ?
(il C e C++ devi fare tu pulizia, ma con tutti i gb di ram di un pc non ci sono problemi)
Il problema poca memoria è su Arduino, non sul PC.
Brunello:
Posta lo sketch, vediamo se è migliorabile
Ti é impossibile darci lo sketch?
domani appena accendo il pc ve lo mando...
Ecco il codice:
#define CAM 9
#define LIGHT 4
#define FAN 8
#define HEATER 5
#define PUMP 7
#define GALL A4
#define SENSOR 12
//Date and time of the clock
#include <swRTC.h>
#include <VirtualWire.h>
#include <EEPROM.h>
swRTC rtc;
const char key[5] = {0x2A,0xF5,0x5F,0xAF,0xDC};
uint8_t buflen = 5;
uint8_t buf[5] = {0x00,0x00,0x00,0x00,0x00};
uint8_t sec = 0;
uint8_t hour = 0;
uint8_t mins = 0;
bool cam = 0;
//light [0] -> ON
//light [1] -> OFF
byte lightTime[2] = {0,23};
bool light = 0;
byte waterTime = 0;
byte fanSec = 0;
byte heaterSec = 0;
byte waterSec = 0;
bool protection = 0;
void setup(){
Serial.begin(9600);
//Load EEPROM Data
lightTime[0] = EEPROM.read(0);
lightTime[1] = EEPROM.read(1);
waterTime = EEPROM.read(2);
fanSec = EEPROM.read(3);
heaterSec = EEPROM.read(4);
waterSec = EEPROM.read(6);
if(heaterSec >fanSec){
heaterSec = fanSec;
EEPROM.write(4,heaterSec);
}
pinMode(GALL, INPUT);
pinMode(CAM, OUTPUT);
pinMode(LIGHT, OUTPUT);
pinMode(FAN, OUTPUT);
pinMode(HEATER, OUTPUT);
pinMode(PUMP, OUTPUT);
protection = (bool)EEPROM.read(5);
rtc.stopRTC();
rtc.setTime(01,01,01); //set the time here
rtc.setDate(1,1,2016);
rtc.startRTC();
vw_set_rx_pin(SENSOR);
// Initialise the IO and ISR
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec
vw_rx_start();
Serial.println("Started!");
}
void loop(){
//sei();
if(Serial.available()){
serialCommand();
}
sec = rtc.getSeconds();
hour = rtc.getHours();
mins = rtc.getMinutes();
if(sec == 0){
if (!protection) {
if(hour >= lightTime[0] && hour < lightTime[1] && light == 0 ){
//Light ON
light = 1;
digitalWrite(LIGHT, HIGH);
}
if(hour >= lightTime[1] && lightTime[0] < hour && light == 1){
//Light OFF
light = 0;
digitalWrite(LIGHT, LOW);
}
if(hour == waterTime && mins == 0 && !protection){
//Water
digitalWrite(PUMP, HIGH);
delay(waterSec*1000);
digitalWrite(PUMP, LOW);
}
//heater & fan
digitalWrite(FAN, HIGH);
digitalWrite(HEATER, HIGH);
}
}
if(sec >= fanSec || protection){
// OFF FAN
digitalWrite(FAN, LOW);
}
if(sec >= heaterSec || protection){
// OFF HEATER
digitalWrite(HEATER, LOW);
}
//TODO: if gall == 1 -> minus water
//TODO: interrupt for Securety on INT0 ALL0
//TODO: Timing (RTC) with check for securety DONE
if(protection){
digitalWrite(LIGHT, LOW);
digitalWrite(CAM, LOW);
digitalWrite(PUMP, LOW);
digitalWrite(HEATER, LOW);
delay(500);
digitalWrite(FAN, LOW);
}
if (vw_get_message(buf, &buflen)) // Non-blocking
{
char i;
char tot = 0;
for (i = 0; i < buflen; i++)
{
if(buf[i] == key[i]){
tot++;
}
}
if(tot > 0){
protection = 1;
}
}
}
void print2digits(int number) {
if (number >= 0 && number < 10)
Serial.write('0');
Serial.print(number);
}
void serialCommand(){
char tmp= Serial.parseInt();
if(tmp == 1){
protection = 0;
EEPROM.write(5,0);
Serial.println("Protection disabled!");
}
if(tmp == 2){
protection = 1;
EEPROM.write(5,1);
Serial.println("Protection enabled!");
}
if(tmp == 3 ){
cam = !cam;
digitalWrite(CAM, cam);
Serial.print("Cam: ");
if(cam){
Serial.println("ON");
}else{
Serial.println("OFF");
}
}
if(tmp == 4){
Serial.println("SET\n1 -> LIGHT\n2 -> ACQUA\n3 -> VENTOLE\n4 -> RISCALDAMENTO\n5 -> OROLOGIO");
while(!Serial.available());
char n = Serial.parseInt();
if(n == 1){
// SET LIGHT
Serial.println("-> A[0-23],S[0-23] (H)");
while(!Serial.available());
lightTime[0] = Serial.parseInt();
lightTime[1] = Serial.parseInt();
EEPROM.write(0, lightTime[0]);
EEPROM.write(1, lightTime[1]);
Serial.println("OK");
return;
}
if(n == 2){
// SET WATER
Serial.println("Acqua: 0-23,S");
while(!Serial.available());
waterTime = Serial.parseInt();
EEPROM.write(2,waterTime);
waterSec = Serial.parseInt();
EEPROM.write(6,waterSec);
Serial.println("OK");
return;
}
if(n == 3){
// SET FAN
Serial.println("FAN: 1-60(S)");
while(!Serial.available());
fanSec = Serial.parseInt();
EEPROM.write(3,fanSec);
if(fanSec < heaterSec){
Serial.println("Riscaldamento: 1-60(S)");
while(!Serial.available());
byte b = Serial.parseInt();
while(b>fanSec){
Serial.println("Riscaldamento: 1-60(S)");
while(!Serial.available());
b = Serial.parseInt();
}
heaterSec = b;
EEPROM.write(4,b);
}
Serial.println("OK");
return;
}
if(n == 4){
//HEATER SET
Serial.println("Risc: 1-60(S)");
while(!Serial.available());
byte b = Serial.parseInt();
while(b>fanSec){
Serial.println("Risc: 1-60(S)");
while(!Serial.available());
b = Serial.parseInt();
}
heaterSec = b;
EEPROM.write(4,b);
Serial.println("OK");
}
if(n == 5){
//CLOCK SET
Serial.println("h, m, s");
while (!Serial.available());
delay(1);
uint8_t h = Serial.parseInt();
uint8_t m = Serial.parseInt();
uint8_t s = Serial.parseInt();
Serial.println(h+m+s);
rtc.stopRTC();
rtc.setDate(1,1,2016);
rtc.setTime(h ,m,s);
rtc.startRTC();
Serial.println("OK");
}
}
if(tmp == 5){
print2digits(hour);
Serial.print(':');
print2digits(mins);
Serial.print(':');
Serial.print(sec);
Serial.println();
Serial.println("LUCE: ");
Serial.print("A: ");
Serial.print(lightTime[0]);
Serial.print(" S: ");
Serial.print(lightTime[1]);
if(light){Serial.println(" ON");}else{Serial.println(" OFF");}
Serial.print("ACQUA: ");
Serial.print(waterTime);
Serial.print(" S: ");
Serial.print(waterSec);
if(digitalRead(GALL)){
Serial.println(" OK");
}else{
Serial.println(" CH");
}
Serial.print("Risc: ");
Serial.println(heaterSec);
Serial.print("Ventole: ");
Serial.println(fanSec);
Serial.print("PROT: ");
if(protection){
Serial.println("YES");
}else{
Serial.println("NO");
}
}
}
è vero che ho un macello di Serial.print… ecc ma comunque penso che dovrebbe quanto meno scrivere correttamente in Seriale… poi se la ram si riempie si resetta (come fanno tutti i micro)…
Intanto usa la macro F()
Serial.println( F("Protection disabled!") );
Nid, mi sono permesso di correggere il tuo post … F() è una macro … definita in WString.h …
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
Guglielmo
Si, okay
a cosa serve quella macro?