Codigo medidor de consumo se me cuelga en attiny85

Hola buenas a todos.

Bueno Voy de problema en problema y creo que este es el mas dificil para mi. Tengo un un sistema de medicion de consumo electrico basado en openenergymonitor.org funcionan muy bien con arduinos, pero me dijeron de usar un attiny85 para ganar sitio en la caja de fusibles y me gusto la idea, vi que en teoria las 2 librerias que uso son compatibles y le decidi a probar mi primera experiencia con este chip.
El problema es que lee la corriente , voltaje y la manda por RF, pero solo 4 veces. luego se para el codigo, lo apago y lo enciendo otra vez y vuelve a ir otros 4 envios… Me imagino que es un problema de memoria. intente quitar del codigo variables que no usaba, pero asi solo manda 0.0.0.0 pero indefinidamente.

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3
#include <VirtualWire.h>
#include "EmonLib.h"             // Include Emon Library
EnergyMonitor emon1;             // Create an instance
   // RF Wirless TX Connection 
  //------------------------------------------------------------
  int tx_pin=0;                            //connection for RF transmitter  
  //------------------------------------------------------------
  
 
  //------------------------------------------------------------
  // Timming Variables 
  //------------------------------------------------------------
  unsigned long previousMillis_power, previousMillis_temp;
  int power_postrate=30000;   //every 30s 
  //int temp_postrate=30000;  //every two min
  //------------------------------------------------------------
  int led = 1;
  
void setup()
{  
   pinMode(led, OUTPUT); 
 // Serial.begin(9600);
  //emonlib
  emon1.voltage(3, 100, 1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(4, 43);       // Current: input pin, calibration.
  
  //------------------------------------------------------------
  // Setup the transmitter
  //------------------------------------------------------------
  vw_set_tx_pin(tx_pin);                      //Transmitter connected to pin 7
  vw_set_ptt_inverted(true);                 // Required for DR3100
  vw_setup(2000);	                     // Bits per
  //------------------------------------------------------------
  
}

void loop()
{
  emon1.calcVI(20,2000);         // Calculate all. No.of half wavelengths (crossings), time-out
 // emon1.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)
  
  float realPower       = emon1.realPower;        //extract Real Power into variable
  float apparentPower   = emon1.apparentPower;    //extract Apparent Power into variable
  float powerFActor     = emon1.powerFactor;      //extract Power Factor into Variable
  float supplyVoltage   = emon1.Vrms;             //extract Vrms into Variable
  float Irms            = emon1.Irms;             //extract Irms into Variable
//------------------------------------------------------------
  // Send Data Via RF
  //------------------------------------------------------------    
   digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
    
  //define variables to send and convert float to integer
  int variableA = (int) supplyVoltage;         
  int variableB = (int) realPower ;
  int variableC = (int) powerFActor;
  int variableD = (int) Irms;
  
  
  char str_rf[30];                          //create string 
  
  itoa(variableA,str_rf,10);               //Convert to string
  strcat(str_rf,"A");                      //Add identifier character
  rfWrite(str_rf);                         //Send the string

  itoa(variableB,str_rf,10);               //Convert to string
  strcat(str_rf,"B");                      //Add identifier character
  rfWrite(str_rf);                         //Send the string
  
  itoa(variableC,str_rf,10);               //Convert to string
  strcat(str_rf,"C");                      //Add identifier character
  rfWrite(str_rf);                         //Send the string
  
  itoa(variableD,str_rf,10);               //Convert to string
  strcat(str_rf,"D");                      //Add identifier character
  rfWrite(str_rf);                         //Send the string

  //------------------------------------------------------------   
  
delay(50);


}

//**************************************************************************************************
// Fuctions 
//**************************************************************************************************

//-----------------------------------------------------------------------------------------------------------------------------------
// Send data via RF 
//---------------------------------------------------------------------------------------------------------------------------------- 
  void rfWrite(const char *msg)
{
  digitalWrite(led,HIGH);
  vw_send((uint8_t *)msg, strlen(msg));
  vw_wait_tx();                              // Wait until the whole message is gone
}
//----------------------------------------------------------------------------------------------------------------------------------

Gracias, ahora caigo que igual seria mejor en software :frowning:

Te recomiendo uses el ide uecide.org este tiene la ventaja de incluir de todo lo que te imaginas como plugin, cores, boards, librerias actuallizadas y te da una estadistica de codigo y memoria consumida.
Se me ocurre que se puede estar desbordando la memoria ram.
Tambien revisa los pines sean compatibles, el de reset no suelen usarlo.
En Adafruit sacaron un miniarduino con attiny85 con bootloader incluido. http://www.adafruit.com/products/1501, facilmente reproducible con formato dip.

Gracias maxid

He instalado el programa que comentas. por ver las estadisticas de uso de memoria que creo que debe ser el problema. Pero no he visto estas estadisticas al compilar. lo que me dice es:

Compiling Libraries...
Linking sketch...
Compiling Done
   text	   data	    bss	    dec	    hex	filename
   6500	    228	    255	   6983	   1b47	/tmp/build-4abc0c85-d0e5-4df8-b77e-e6ec72a03321/TX_voltage_and_current_con_rf_v2_attiny85.elf

El programa parece muy interesante pero no veo ni las librerias ni estadisticas. Creo que puede ser hay que instalarlas a mano. o el otro compilador. Si me pudieras ayudar porque mi googleGLES (dicese del ingles taducido con google ;-)) es muy malo

El pin reset no lo uso. uso el 0 y 1 para RF y LED respectivamente y el 3 y 4 analogicos para voltaje y corriente respectivamente.
Creo que el problema puede ser la ram, pero cuando pruebo quitar variables que en realidad ahora no uso. no recibo nada. solo 0.0.0.0 donde cada 0 deberia ser una variable.

El Trinket muy interesante, pero para mi es demasiado grande, por un poco mas usaria un mini. pero necesito que sea lo mas pequeño posible. para meter el tranformador, (“arduino” + unas pocas resistencias y 2 condensadores )y la pinza de corriente. dentro de la caja de magnetotermicos de mi casa. la verdad es que un attiny seria la bomba :smiley:

Gracias!

¿El código que te funciona bien cuatro veces es el que pones en el primer post de este hilo, o ese es el que te devuelve ceros?
Lo comento, porque si quieres puedo intentar modificarlo para optimizar un poco el uso de ram a ver si conseguimos que se mantenga en funcionamiento.

Despues de instalarlo vas a Plugin Manager y ahi instalas todo lo que necesites.
Despues cuando complita te tira el consumo de ram y rom

ejemplo: el mismo programa blink
UNO:
Program Size:
Flash: 3% (1084 bytes out of 32256 bytes max)
RAM: 11 bytes

con ATTINY85:
Program Size:
Flash: 10% (870 bytes out of 8192 bytes max)
RAM: 11 bytes

LEONARDO:
Program Size:
Flash: 16% (4826 bytes out of 28672 bytes max)
RAM: 157 bytes

noter si el codigo que va 4 veces es el del primer post, pero cuando quito variables… lo cago. La verdad es que las variables que ahora uso en el receptor son variableA y variableB, las demas ahora son prescindibles.
aqui he quitado hasta el led :smiley: Pero no recibo nada

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3
#include <VirtualWire.h>
#include "EmonLib.h"             // Include Emon Library
EnergyMonitor emon1;             // Create an instance
   // RF Wirless TX Connection 
  //------------------------------------------------------------
  int tx_pin=0;                            //connection for RF transmitter  
  //------------------------------------------------------------
  
 
//  //------------------------------------------------------------
//  // Timming Variables 
//  //------------------------------------------------------------
//  unsigned long previousMillis_power, previousMillis_temp;
//  int power_postrate=30000;   //every 30s 
//  //int temp_postrate=30000;  //every two min
//  //------------------------------------------------------------
 // int led = 1;
  
void setup()
{  
 //  pinMode(led, OUTPUT); 
 // Serial.begin(9600);
  //emonlib
  emon1.voltage(3, 100, 1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(4, 43);       // Current: input pin, calibration.
  
  //------------------------------------------------------------
  // Setup the transmitter
  //------------------------------------------------------------
  vw_set_tx_pin(tx_pin);                      //Transmitter connected to pin 7
  vw_set_ptt_inverted(true);                 // Required for DR3100
  vw_setup(2000);	                     // Bits per
  //------------------------------------------------------------
  
}

void loop()
{
  emon1.calcVI(20,2000);         // Calculate all. No.of half wavelengths (crossings), time-out
 // emon1.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)
  
//  float realPower       = emon1.realPower;        //extract Real Power into variable
//  float apparentPower   = emon1.apparentPower;    //extract Apparent Power into variable
//  float powerFActor     = emon1.powerFactor;      //extract Power Factor into Variable
//  float supplyVoltage   = emon1.Vrms;             //extract Vrms into Variable
//  float Irms            = emon1.Irms;             //extract Irms into Variable
//------------------------------------------------------------
  // Send Data Via RF
  //------------------------------------------------------------    
 //  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
    
  //define variables to send and convert float to integer
  int variableA =  emon1.Vrms;         
  int variableB =  emon1.realPower;
 // int variableC =  emon1.powerFactor;
  //int variableD =  emon1.Irms;
  
  
  char str_rf[30];                          //create string 
  
  itoa(variableA,str_rf,10);               //Convert to string
  strcat(str_rf,"A");                      //Add identifier character
  rfWrite(str_rf);                         //Send the string

  itoa(variableB,str_rf,10);               //Convert to string
  strcat(str_rf,"B");                      //Add identifier character
  rfWrite(str_rf);                         //Send the string
  
//  itoa(variableC,str_rf,10);               //Convert to string
//  strcat(str_rf,"C");                      //Add identifier character
//  rfWrite(str_rf);                         //Send the string
//  
//  itoa(variableD,str_rf,10);               //Convert to string
//  strcat(str_rf,"D");                      //Add identifier character
//  rfWrite(str_rf);                         //Send the string

  //------------------------------------------------------------   
  
//delay(50);


}

//**************************************************************************************************
// Fuctions 
//**************************************************************************************************

//-----------------------------------------------------------------------------------------------------------------------------------
// Send data via RF 
//---------------------------------------------------------------------------------------------------------------------------------- 
  void rfWrite(const char *msg)
{
 // digitalWrite(led,HIGH);
  vw_send((uint8_t *)msg, strlen(msg));
  vw_wait_tx();                              // Wait until the whole message is gone
}
//----------------------------------------------------------------------------------------------------------------------------------

Maxid perdon pero creo que la ultima version no lo lleva de serie o algo. por lo menos en linux. he bajado todos los plugins y todo lo relacionado con arduino y attiny, y probado varios compiladores, en las preferencias tampoco veo nada. Es una pena. con eso y algunas mejoras mas seria un ide muy bueno.

Gracias a los 2

Creo que tu respuesta está en la misma pagina del VirtualWire.

Caution: ATTiny85 has only 2 timers, one (timer 0) usually used for millis() and one (timer 1) for PWM analog outputs. The VirtualWire library, when built for ATTiny85, takes over timer 0, which prevents use of millis() etc but does permit analog outputs.

Por otra parte el ide es espectacular, importa libreria de terceros indicando el zip. note que no da los totales en linux, pero es por configuracion. el desarrollador esta todo el tiempo recibiendo propuestas y responde en el momento.
Ya le voy a tirar la inquietud.

Maxid perdon pero no entiendo lo de virtualwire :frowning: mi googleGles es muy malo :frowning: dice que el timer0 es el que usa y no puede usar para lo millis y que emonlib necesita los millis? es que esto es de un curso mas avanzado, pero quiero aprender. :slight_smile:

Sobre el IDE. Me gustan muchas cosas. Pero otras poco. lo que mas me gusta es que te permite tener solo las placas que usas. Eso es genial. yo solo tengo 3 placas y en el ide de arduino tengo mas de 20, es un lio.

lo malo de este ide, es que en una maquina virtual con xp, despues de bajar las placas y plugins se me cerro y ya no me aparecen las placas y no puedo acceder al menu tools. Desinstalo y vuelvo a instalar y sigue igual. Luego buscare las carpetas y las borrare a mano
yo permitiria bajar versiones anteriores de la web

Tambien echo en falta poder Comentar/Descomentar muy util

Bueno es la instalacion en linux solo descomprimir :slight_smile:

Muy util si tienes otras plataformas como raspberry py y/o pics.

aunque no lo parezca me gusta el ide y lo ire siguiendo.

otra sujerencia :wink: seria añadir placas pinguino.
Te lo digo porque si tu hablas ingles y algo de esto te parece interesante se lo puedas tansmitir al desaroyador

Saludos

aca hay un ejemplo de usar virtualwire

Lo compilé y me da esto
Program Size:
Flash: 79% (6532 bytes out of 8192 bytes max)
RAM: 477 bytes

De ram estamos bien. Pero encontré esto del mismo desarrollador http://openenergymonitor.org/emon/node/1187
Pero leyendo el codigo usa Millis() por lo que estaria en incompatibilidad con VirtualWire por usar la libreria y la funcion Millis() el Timer0

void EnergyMonitor::calcVI(int crossings, int timeout)
{
#if defined emonTxV3
int SUPPLYVOLTAGE=3300;
#else
int SUPPLYVOLTAGE = readVcc();
#endif

int crossCount = 0; //Used to measure number of times threshold is crossed.
int numberOfSamples = 0; //This is now incremented

//-------------------------------------------------------------------------------------------------------------------------
// 1) Waits for the waveform to be close to ‘zero’ (500 adc) part in sin curve.
//-------------------------------------------------------------------------------------------------------------------------
boolean st=false; //an indicator to exit the while loop

unsigned long start = millis(); //millis()-start makes sure it doesnt get stuck in the loop if there is an error.

while(st==false) //the while loop…
{
startV = analogRead(inPinV); //using the voltage waveform
if ((startV < (ADC_COUNTS/2+50)) && (startV > (ADC_COUNTS/2-50))) st=true; //check its within range
if ((millis()-start)>timeout) st = true;
}

haz una prueba para descartar esto, usa la libreria SerialSoft para saber que envia datos. Y si es esto tendrias que habrir un bug en el github del desarrollador para solucionarlo porque la ultima version no refleja los cambios

Con respecto al Ide, me paso eso mismo. En la carpeta de tu usuario se crea una UECIDE borra esa y comienza de nuevo, pero primero con los compiladores, cores y placas es ense orden. Me paso una vez pero despues nunca mas.
Lo bueno de este IDE es que se actualizan las llibrerias y cores y no debes reinstalar nada entre cambio de versiones.
El desarrollador es del foro en ingles. En linux lo instale con un .deb en ubuntu y en opensuse desde los fuentes cero problemas

¿Y si se modificara Virtualwire para que use el timer 1 en lugar de 0? Suponiendo que no se necesite usar en el proyecto salidas analógicas.

hay que revisar el core tiny si no lo usa

Pero antes de tocar la libreria yo probaria con un simple transmicion serial. Solo para asegurar que no se cuelga.

Hola maxid

anoche lo estube probando con 2 librerias softwareserial y newsoftserial junto con el primer codigo y me dan este error al compilar

In file included from TX_voltage_and_current_con_rf_v2_attiny85.ino:9:
C:\arduino-1.0.5-r2\libraries\NewSoftSerial/NewSoftSerial.h:33:2: error: #error NewSoftSerial has been moved into the Arduino core as of version 1.0. Use SoftwareSerial instead.
In file included from TX_voltage_and_current_con_rf_v2_attiny85.ino:9:
C:\arduino-1.0.5-r2\libraries\NewSoftSerial/NewSoftSerial.h:99: error: conflicting return type specified for 'virtual void NewSoftSerial::write(uint8_t)'
C:\arduino-1.0.5-r2\hardware\tiny\cores\tiny/Print.h:73: error:   overriding 'virtual size_t Print::write(uint8_t)'

comentando todo lo del segundo codigo que puse y mas cosas, me cambia el error y dice que es demasiado grande 8,5xkb
frente a 8,14kb que caben. asi que creo que no puedo poner las 3 librerias en un attiny85 :frowning:

Lo que no entiendo es porque con el primer codigo manda 4 veces bien los datos del consumo y se cuelga. pero cuando quito variables que no uso solo manda CEROS. y no se cuelga.

El proyecto no usa salidas analogicas, pero si entradas analogicas y salidas digitales, me imagino que no afectara a estas, no?

a el consumo de ram es del primer codigo con sus librerias? por que seria perfecto :slight_smile:

Muchas gracias por tu tiempo, Espero que lo podamos sulucionar

Maxid creo que no te entendi la primera vez.

Ahora he probado la libreria emonlib y softserial SIN virtualwire y funciona. leo los datos por serial muy rapido y bien.

Tambien he probado cambiar el valor de VW_TIMER_INDEX a 0, 1 y 2 en virtualwire_config no se si lo he echo bien. pero no funciona. tambien lo intente en el codigo del primer ejemplo añadiendo despues de la libreria virtualwire, #define VW_TIMER_INDEX a 0, 1 y 2 y tampoco funciona.

Sabes como vambiar el timer?

Gracias!

Como te dije es problema de la libreria.
La verdad que no se como cambiarlo, pero dejame verlo en unos dias te cuento.

Me ouse a leer la evolucion de cambios y llegue al final donde dice esto que es muy importante.

version 1.27 Reinstated VWutil/crc16.h for the benefit of other platforms such as Teensy.
Testing on Teensy 3.1. Added End Of Life notice. This library will no longer be maintained
and updated: use RadioHead instead.

Por lo que entiendo no la mantienen mas y ahi va a quedar y resolvieron otra mejor

http://www.airspayce.com/mikem/arduino/RadioHead/

Hola

Maxid La verdad es que sabie que virtualwire ya no tenia mas apollo :frowning: Pero aun asi la eleji por que es la que conocia un poco y tiene mucha informacion por la red. :smiley: ademas creo que hace menos de un año que ya no lo tiene. y todo lo que uso es mas antiguo.

Probare portar el codigo a la nueva libreria, que ahora que la miro no parece tan diferente.

sobre virtualwire CREO que si usas millis cambia el timer solo.

/*=============================================================================
  Assume there are only two timers.  One for millis and one for everything 
  else.
=============================================================================*/

#if TIMER_TO_USE_FOR_MILLIS == 0
#define TIMER_TO_USE_FOR_USER                    1 /este era 1
#elif TIMER_TO_USE_FOR_MILLIS == 1
#define TIMER_TO_USE_FOR_USER                     0 / este era 0
#else
#error Unexpected condition in UserTimer.h.
#endif

Porque probe virtualwire y el ejemplo del fader led y no funciona. Y creo que si usara el timer0 no seria capaz de mandar 4 veces el voltaje correctamente y luego cuelgarse.
Tampoco entiendo porque si quito y acorto el codigo int variableA = emon1.Vrms; sin pasar antes por float no se cuelga pero solo recibo 0.0.0.0 . cuando con arduino nano va ok.

Me podrias ayudar a optimizar el codigo para bajar el uso de ram?

Yo voy a probar emonlib con el segundo codigo y verlo por softserial a ver si pueda ser lo que falla y por eso manda 0.0.0.0

Gracias :slight_smile:

Hola

Bueno la prueba emonlib con el segundo codigo y puerto serie va super bien. ASi el problema si esta en cuando manda. es una pena que no puedo poner las 3 librerias para ver por serial lo que pasa :frowning:

sobre la nueva libreria de RF no compila en mi attiny85 tira este error el ide

In file included from ask_transmitter.pde:10:
C:\arduino-1.0.5-r2\libraries\SPI/SPI.h: In static member function 'static byte SPIClass::transfer(byte)':
C:\arduino-1.0.5-r2\libraries\SPI/SPI.h:56: error: 'SPDR' was not declared in this scope
C:\arduino-1.0.5-r2\libraries\SPI/SPI.h:57: error: 'SPSR' was not declared in this scope
C:\arduino-1.0.5-r2\libraries\SPI/SPI.h:57: error: 'SPIF' was not declared in this scope
C:\arduino-1.0.5-r2\libraries\SPI/SPI.h: In static member function 'static void SPIClass::attachInterrupt()':
C:\arduino-1.0.5-r2\libraries\SPI/SPI.h:63: error: 'SPCR' was not declared in this scope
C:\arduino-1.0.5-r2\libraries\SPI/SPI.h:63: error: 'SPIE' was not declared in this scope
C:\arduino-1.0.5-r2\libraries\SPI/SPI.h: In static member function 'static void SPIClass::detachInterrupt()':
C:\arduino-1.0.5-r2\libraries\SPI/SPI.h:67: error: 'SPCR' was not declared in this scope
C:\arduino-1.0.5-r2\libraries\SPI/SPI.h:67: error: 'SPIE' was not declared in this scope

Parece que no tiene puerto SPI :frowning: he probado con una libreria spi (llamada TinyWireM)para attiny pero claro no usa los mismos nombres… no compila.

no se que mas probar :frowning:

Saludos

con tan pocos pines no le puedes pedir tambien spi!!!! ya mas no cabe.
Lo de enviar 0 puede ser por un truncado propio de C, todo numero cercano lo redondea