Arduino (IoT): Simple Tutorial Válvula Solenoide con MOSFET

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Válvula Solenoide con MOSFET

En este tutorial introducimos otros switch digital basado en transistores, el MOSFET!

Requisitos:

  1. Computadora (mac)
  2. Arduino UNO
  3. Válvula Solenoide de 12V
  4. MOSFET IRLB-8721
  5. Diode
  6. Batería 12VDC Lead-Acid (de algún UPS)
  7. Breadboard
  8. Arduino IDE (https://www.arduino.cc/en/Main/Software)
Arduino IoT: Simple Tutorial Solenoide con MOSFET by Santiapps Marcio Valenzuela
Arduino IoT: Simple Tutorial Solenoide con MOSFET

Una válvula solenoide no es mas que una válvula controlada por un electromagnet, que es esencialmente un motor invertido.  Sabemos entonces que los motores generan contra corrientes.  Como podemos ver en el diagrama de arriba, debemos alimentar la válvula de una fuente y proteger el cerebro (Arduino) de las contra corrientes a través de un diodo.

Entra el MOSFET!  Este dispositivo es muy similar a un transistor BJT como el TIP-120, pero es capaz de operar a mayores voltages.  Y esa es la clave, porque a diferencia de un BJT, el flujo de corriente no se activa por medio de un flujo de corriente a la Base como en el caso del BJT.  En el caso del MOSFET el flujo de corriente se activa con un campo (field) eléctrico en la Base.

Otra diferencia es que donde en un BJT tenemos la Base, en el MOSFET tenemos el Gate.  Y el flujo de corriente que queremos controlar no es entre Emitter y Collector sino entre Source y Drain.

Arduino IoT: Simple Tutorial Valvula Solenoid Santiapps Marcio Valenzuela
Arduino IoT: Simple Tutorial Valvular Solenoid with MOSFET

Aquí vemos como una señal desde el pin 3 hacia el Gate del MOSFET IRLB8721 abre el flujo para que la solenoide complete el circuito a tierra y como el diodo controla dicho flujo en una sola dirección.

Como seleccionar un MOSFET:

Vds

Vgs

RDSon

ROJA

El código:

/* MOSFET IRLB8721
This sketch will blink a LED and at the same time, use the MOSFET to open a 12V solenoid.
Arduino D10 : To LED (Through 330 Ohm Resistor)
Arduino D02 : To MOSFET Gate
*/
int ledPin = 13; // Connect the pin to Arduino pin 13
int mosfetPin = 3; // Connect the MOSFeT Gate (first pin on the left, when writing on the chip is facing you) to Arduino pin 3
void setup(){
 pinMode(ledPin, OUTPUT);
 pinMode(mosfetPin, OUTPUT);
}
void loop(){
 digitalWrite(ledPin, HIGH);
 digitalWrite(mosfetPin, HIGH);
 delay(5000); // Will turn both the LED and the MOSFET on for 60s, it gives you plenty of time to see if water is flowing as expected!
 digitalWrite(ledPin, LOW);
 digitalWrite(mosfetPin, LOW);
 delay(5000); // Will shut down everything for 5s and restart.
}

Las conexiones finales usando el perf board se pueden ver aquí:

Arduino IoT: Simple Tutorial Solenoide con MOSFET
Arduino IoT: Simple Tutorial Solenoide con MOSFET

y el video final se puede ver aquí:

Controlar el flujo de un liquido puede ser muy util para regar plantas y muchas otras aplicaciones mas.

Arduino (IoT): Simple Tutorial de Transistores BJT, JFET & MOSFET

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial de Transistores BJT, JFET & MOSFET

En este tutorial hacemos un alto en el camino y repasamos un poco de teoría para entender PN-Junctions, Diodes, BJTs, JFETs y MOSFETs.

Requisitos:

  1. Computadora (mac)
  2. Arduino UNO
  3. Válvula Solenoide de 12V
  4. TIP120 Transistor, Diode N4148, MOSFET IRLB8721
  5. 2 baterias de 9V
  6. Breadboard
  7. Arduino IDE (https://www.arduino.cc/en/Main/Software)

 

Primero entendamos que es un PN-Junction:

pnjunction

Una PN junction se forma al unir 2 semiconductores de distinta composición llamados n-type y p-type.  El n-type tiene mas electrones lo cual atrae hoyos positivos de la p-type.  La p-type tiene mas hoyos positivos lo cual atrae electrones de la n-type.  Esto crea una banda donde no hay flujo eléctrico después de alcanzar este equilibrio debido a que los electrones negativos del n-type quedan bloqueados por la carga positiva de la banda (pn-junction) y vv al otro lado.  Esto es algo muy deseable como veremos.

Arduino IoT PN Junction
Arduino IoT PN Junction

Aquí podemos ver en la izquierda como la banda o pnj creada se llama un Depletion Region a través de la cual no hay flujo eléctrico.  Ahora si conectamos una fuente de poder de forma que le n-type esta conectada a la terminal + de la fuente, los electrones de la n-type son atraídos a la terminal + y vv del otro lado.  Esto agranda la Depletion Zone y el flujo eléctrico se asegura o se restringe aun mas.  Esto se llama Reverse bias y es así como funciona un Diode.

Arduino IoT PN Junction
Arduino IoT PN Junction

En un Diode, si el pnj esta reversed biased, no fluye corriente. Y de que sirve esto!?  Pues en primera instancia, para restringir el flujo de corriente cuando no lo queremos.  Esto es importante para proteger circuitos delicados y caros.  Ahora veamos como hacer que SI fluya la corriente!

Arduino IoT PN Junction
Arduino IoT PN Junction

Si conectamos la bateria con la terminal + al p-type y vv, lo que hacemos es forward bias.  Ahora a pesar que hay una pnj en el centro del pn sandwich a traves de la cual no hay flujo eléctrico, al conectar la bateria los electrones en el n-type son empujados por los electrones negativos de la bateria.  Los hoyos positivos del p-type son empujados por la terminal positiva de la bateria.  Ahora si hay flujo a traves de la pnj.  Aquí tenemos otra representación del pnj que la hacemos Reverse Bias.

Arduino IoT PN Junction
Arduino IoT PN Junction

 

Ahora hagamos algo mas interesante.  En un sandwich de NPN se crean 2 pnj.  No hay flujo eléctrico a menos que apliquemos un pequeño potencial forward bias entre el Emitter y la Base.  Al lograr esto y teniendo otro potencial mas grande conectado entre Emitter y Collector, y debido a que el Emitter es construido con mucho mas electrones que el Collector, los electrones del Emitter viajan a través de las pnj hacia el Collector y los electrones del Collector son atraídos por la terminal + de la fuente de poder.  Voila!  Ahora tenemos un switch digital y esto se llama un BJT!

Arduino IoT PN Junction
Arduino IoT PN Junction

Ahora pasemos a JFETs…

Arduino IoT BJTs JFETs MOSFETs
Arduino IoT BJTs JFETs MOSFETs

Ahora MOSFETs Depletion…

Arduino IoT BJTs JFETs MOSFETs
Arduino IoT BJTs JFETs MOSFETs

Finalmente MOSFETs Depletion/Enhancement…

Arduino IoT BJTs JFETs MOSFETs
Arduino IoT BJTs JFETs MOSFETs

Tratemos de operar una solenoide usando estos componentes.  Pero primero establezcamos los valores de nuestra solenoide usando un multimeter.

  1. Midamos la resistencia de una VDC = 42Ohms = 285mA
  2. Midamos el amperaje = 195mA

Arduino (IoT): Simple Tutorial de PNJ & Diodes

//rcm-na.amazon-adsystem.com/e/cm?o=1&p=13&l=ez&f=ifr&linkID=50610450ab57eae036291d286ac2abd5&t=santiapps17-20&tracking_id=santiapps17-20

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial de PNJ & Diodes

En este tutorial exploramos la base de BJTs y FETs.

Vimos que es un PN-Junction:

pnjunction

Una PN junction se forma al unir 2 semiconductores de distinta composición llamados n-type y p-type.  El n-type tiene mas electrones lo cual atrae hoyos positivos de la p-type.  La p-type tiene mas hoyos positivos lo cual atrae electrones de la n-type.  Esto crea una banda donde no hay flujo eléctrico después de alcanzar este equilibrio debido a que los electrones negativos del n-type quedan bloqueados por la carga positiva de la banda (pn-junction) y vv al otro lado.  Esto es algo muy deseable como veremos.

Arduino IoT PN Junction
Arduino IoT PN Junction

Aquí podemos ver en la izquierda como la banda o pnj creada se llama un Depletion Region a través de la cual no hay flujo eléctrico.  Ahora si conectamos una fuente de poder de forma que le n-type esta conectada a la terminal + de la fuente, los electrones de la n-type son atraídos a la terminal + y vv del otro lado.  Esto agranda la Depletion Zone y el flujo eléctrico se asegura o se restringe aun mas.  Esto se llama Reverse bias y es así como funciona un Diode.

Una forma diferente de explicar es en este diagrama.  Aquí vemos que cuando una pnj se Forward Bias, fluye corriente de + a -.  (NOTA:Esta es la conceptualizacion convencional de la corriente.  En realidad lo que fluye son los electrones en dirección opuesta).  Es por esto que un diode esta Forward Bias en la dirección que queremos via una Depletion Layer o Region delgada.  Por otro lado, un pnj Reverse Biased ocurre cuando la corriente quiere fluir en sentido contrario.  Es aquí donde la Depletion Region se ensancha y no permite el flujo.

Arduino IoT PNJ Diodes
Arduino IoT PNJ Diodes

Aqui podemos ver otra terminologia:

Arduino IoT PNJ Diodes
Arduino IoT PNJ Diodes

Flujo de corriente (convencional) es de Anodo a Catodo (k), ossa de + a -.  Este flujo si esta permitido en un Diode.

Aqui otra imagen:

Arduino IoT PNJ Diodes
Arduino IoT PNJ Diodes

Nuevamente, la corriente convencional no se permite fluir de Catodo a Anodo pero si de Anodo a Catodo.

Arduino (IoT): Simple Tutorial Seguridad Biometrica Huella Digital 3/3

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Seguridad Biometrica Huella Digital

En este tutorial usamos un modulo biometrico de huella digital para brindar seguridad a nuestros proyectos.

Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital Santiapps Marcio Valenzuela
Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital

Requisitos:

  1. Computadora (mac)
  2. Arduino UNO
  3. FPS GT511-c1R FPS
  4. Resistores
  5. Breadboard
  6. Arduino IDE (https://www.arduino.cc/en/Main/Software)

El setup continua igual.  Ahora cambiamos el codigo para comparar las huellas digitales en el modulo.

Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital Santiapps Marcio Valenzuela
Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital

El código:

</pre>
<pre>#include "FPS_GT511C3.h"
#include "SoftwareSerial.h"
//FPS connected to pin 4 and 5 - see previous schemas
FPS_GT511C3 fps(4, 5);
void setup(){
  Serial.begin(9600);
  delay(100);
  fps.Open();
  fps.SetLED(true);
}
void loop(){
  // if a finger is on the sensor
  if (fps.IsPressFinger()){
    //capture the finger print
    fps.CaptureFinger(false);
    //get the id
    int id = fps.Identify1_N();
    //maximun finger print stored in 200. 
    //Id > 200 is a not recognized one
    if (id <200){
      //finger print recognized: display the id
      Serial.print("Verified ID:");
      Serial.println(id);
      // ...
      // add you code here for the condition access allowed
      // ...
    }else{
      //finger print not recognized
      Serial.println("Finger not found");
       // ...
      // add you code here for the condition access disallowed
      // ...
    }
  }else{
    // wait for finger
    Serial.println("Please press finger");
  }
  delay(100);
}

Al conectar la UNO podemos comparar nuestra huella digital.  Si quisiéramos borrar las huellas digitales solo tenemos que usar el comando:

fps.<span class="pl-c1">DeleteAll</span>();

 

Arduino (IoT): Simple Tutorial Seguridad Biometrica Huella Digital 2/3

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Seguridad Biometrica Huella Digital

En este tutorial usamos un modulo biometrico de huella digital para brindar seguridad a nuestros proyectos.

Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital Santiapps Marcio Valenzuela
Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital

Requisitos:

  1. Computadora (mac)
  2. Arduino UNO
  3. FPS GT511-c1R FPS
  4. Resistores
  5. Breadboard
  6. Arduino IDE (https://www.arduino.cc/en/Main/Software)

El setup continua igual.  Ahora cambiamos el codigo para registrar huellas digitales en el modulo.

Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital Santiapps Marcio Valenzuela
Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital

El código:

#include "FPS_GT511C3.h"
#include "SoftwareSerial.h"
//FPS connected to pin 4 and 5 - see previous schemas
FPS_GT511C3 fps(4, 5);
void setup(){
 Serial.begin(9600);
 //display messages on the classical serial teminal - DEBUG 
 fps.UseSerialDebug = true; 
 Serial.println("before open");
 fps.Open();
 //call Enroll to add fingerprint
 Serial.println("before enroll");
 enroll();
}
void enroll(){
 // get the first available id for new finger print
 int enrollid = 0;
 bool usedid = true;
 Serial.println("before while");
 while (usedid == true){
 usedid = fps.CheckEnrolled(enrollid);
 if (usedid==true) enrollid++;
 }
 Serial.println("before enrollstart");
 //enrollment start here with the first free id
 fps.EnrollStart(enrollid);
 Serial.print("Press finger to Enroll #");
 Serial.println(enrollid);
 // ***** FIRST MEASURE *****
 // wait for finger press
 while(fps.IsPressFinger() == false) delay(100);
 bool bret = fps.CaptureFinger(true);
 int iret = 0;
 if (bret != false){
 //has a finger print captured
 Serial.println("Remove finger");
 // Enroll step 1
 fps.Enroll1(); 
 //wait for finger removed
 while(fps.IsPressFinger() == true) delay(100);
 // ***** SECOND MEASURE *****
 // Now we need to check the finger print 
 // wait for finger press
 Serial.println("Press same finger again");
 while(fps.IsPressFinger() == false) delay(100);
 bret = fps.CaptureFinger(true);
 if (bret != false){
 Serial.println("Remove finger");
 //enroll step 2
 fps.Enroll2();
 //wait for finger removed
 while(fps.IsPressFinger() == true) delay(100);
 // ***** THIRD MEASURE *****
 //Check Again the finger print
 Serial.println("Press same finger yet again");
 while(fps.IsPressFinger() == false) delay(100);
 bret = fps.CaptureFinger(true);
 if (bret != false){
 Serial.println("Remove finger");
 iret = fps.Enroll3();
 if (iret == 0){
 //*** SUCCESS third measure are the same -> NOW finger print is stored
 Serial.println("Enrolling Successfull");
 }else{
 //*** FAIL For some reason -> NOTHING STORED
 Serial.print("Enrolling Failed with error code:");
 Serial.println(iret);
 }
 }
 else Serial.println("Failed to capture third finger");
 }
 else Serial.println("Failed to capture second finger");
 }
 else Serial.println("Failed to capture first finger");
}
//loop is useless here
void loop(){
 delay(100000);
}

Al conectar la UNO podemos registrar nuestra huella digital.

Arduino (IoT): Simple Tutorial Seguridad Biometrica Huella Digital 1/3

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Seguridad Biometrica Huella Digital

En este tutorial usamos modulo FPS para agregar seguridad biometrica a nuestros proyectos.

Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital Santiapps Marcio Valenzuela
Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital

Requisitos:

  1. Computadora (mac)
  2. Arduino UNO
  3. FPS GT511-c1R FPS
  4. Resistores
  5. Breadboard
  6. Arduino IDE (https://www.arduino.cc/en/Main/Software)

El modulo requiere 3.3V y es por eso que usamos 2 resistores para crear un voltage divider para generar 3.3V de los 5V proveídos por la Arduino UNO, o se puede usar el pin de 3.3V.

El setup se ve asi:

Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital Santiapps Marcio Valenzuela
Arduino (IoT) Simple Tutorial Seguridad Biometrica Huella Digital

Vamos a usar una library para facilitar el uso del modulo.  La podemos descargar aqui: https://github.com/sparkfun/Fingerprint_Scanner-TTL

En el primer tutorial queremos simplemente saber si el modulo esta funcionando.

El código:

#include "FPS_GT511C3.h"
#include "SoftwareSerial.h"
FPS_GT511C3 fps(4, 5);
void setup(){
  Serial.begin(9600);
  fps.UseSerialDebug = true; 
  fps.Open();
}
void loop(){
  //blink the led
  fps.SetLED(true);
  delay(1000);
  fps.SetLED(false);
  delay(1000);
}

Al conectar la UNO podemos ver como el modulo enciende y apaga su LED interna repetitivamente.  Ahora sabemos que el modulo esta funcionando.  Si no funciona asi, sera necesario medir el voltage saliente del voltage divider para asegurar que estamos obteniendo los 3.3V requeridos.

Arduino (IoT): Proyecto Monitor Remoto de Temp y Humedad Cafe Honduras

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Monitor Remoto de Cafe

En este proyecto construimos un monitor de temperatura y humedad para monitorear las condiciones en una bodega de cafe.

Arduino IoT Proyecto Monitor Remoto Temperatura Humedad Cafe Honduras by Santiapps Marcio Valenzuela
Arduino IoT Proyecto Monitor Remoto Temperatura Humedad Cafe Honduras

Requisitos:

  1. Computadora (mac)
  2. Arduino Nano
  3. DHT11
  4. Modulo SIM900 GSM
  5. Breadboard
  6. Arduino IDE (https://www.arduino.cc/en/Main/Software)

El código (SIM900NanoW_OLibrary):

#include <Time.h>
#include <TimeLib.h>
#include <SoftwareSerial.h>
#include <TimeAlarms.h>
#include <dht.h>

dht DHT;
#define DHT11_PIN 5
char number[]="+504numero";
boolean started=false;
SoftwareSerial sim900(9,10);

void setup(){
Serial.begin(9600);
Alarm.timerRepeat(21600, MainAlarm); //21600s/60s/m=360m
}

void loop(){
Alarm.delay(10); // wait one second between clock display
}

void MainAlarm(){
Serial.println("Main Alarm...");
int chk = DHT.read11(DHT11_PIN);
Serial.print("Temperature = ");
double temp = DHT.temperature;
Serial.println(DHT.temperature);
Serial.print("Humidity = ");
double hum = DHT.humidity;
Serial.println(DHT.humidity);
sendData(temp,hum);
}

void sendData(double temp, double hum){
sim900.begin(9600); //Default serial port setting for the GPRS modem is 19200bps 8-N-1

static char outTempStr[15];
static char outHumStr[15];
String tempString = dtostrf(temp,5,2,outTempStr);
String humString = dtostrf(hum,5,2,outHumStr);

delay(10000);
sim900.print("\r");
delay(1000); //Wait for a second while the modem sends an "OK"
sim900.print("AT+CMGF=1\r"); //text mode
delay(1000);
sim900.print("AT+CMGS=\"+504numero\"\r");
delay(1000);
sim900.print("Temp=" + tempString +  "Hum=" + humString); //The text for the message
sim900.print("\r"); //EOL message
delay(1000);
sim900.write(0x1A); //Equivalent to sending Ctrl+Z
}


Asi podemos reportar las condiciones de manera constante.  Podríamos agregar una fuente solar recargable de poder.

Arduino (IoT): Simple Tutorial para Medir Voltaje con Arduino

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial de Medición de Voltaje

En este tutorial usamos una Arduino para medir voltaje.

Requisitos:

  1. Computadora (mac)
  2. Arduino Nano
  3. LCD 16×02
  4. Potenciometro
  5. Breadboard
  6. Arduino IDE (https://www.arduino.cc/en/Main/Software)
Simple Tutorial Medicion Voltaje Arduino Santiapps Marcio Valenzuela
Simple Tutorial Medicion Voltaje Arduino

El código incorpora lo que vimos para mostrar información en una pantalla LCD 16×2 y el uso de resistencias para dividir el voltaje a ser medido para que la Arduino no se dañe.  El código es así:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);   // Pines de data de LCD
float vin=0.0;
float temp=0.0;
float r1=100000.0;                       // Resistor 1
float r2=10000.0;                       // Resistor 2
void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);                    // Cols y filas del lcd 
  lcd.print("Santiapps");             // Imprimir saludo.
  delay(1000);
  lcd.clear();
  lcd.print("DC Voltimetro");
}
void loop() {
  int analog_val=analogRead(A0);      // leer pin analogo A0
  temp = (analog_val * 5.0)/1024.0;   // Si se mide hasta 5V
  vin = temp/(r2/(r1+r2));
  if(vin<0.1){
    vin=0.0;
  }
  lcd.setCursor(0, 1);        // Col 0, fila 1
  lcd.print("Voltage = ");    // Mostrar voltaje
  lcd.println(vin);
  delay(300);
}

Las conexiones son asi:

Simple Tutorial Medicion Voltaje Arduino Santiapps Marcio Valenzuela
Simple Tutorial Medicion Voltaje Arduino

Esto es muy útil cuando tenemos proyectos conectados a baterías y queremos monitorear el nivel de carga.

Arduino (IoT): Simple Tutorial GPS Top Titan 3 Glonass: Parte 2

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial GPS Top Titan 3: Parte 2

En este tutorial recibiremos datos de un modulo GPS usando la library TinyGPS.

Requisitos:

  1. Computadora (mac)
  2. Arduino MEGA
  3. Modulo Top Titan 3 GPS/Glonass
  4. Breadboard
  5. Arduino IDE (https://www.arduino.cc/en/Main/Software)
Arduino IoT: Simple Tutorial GPS Titan3 Santiapps Marcio Valenzuela
Arduino IoT: Simple Tutorial GPS Titan3

La conexión:

  • GPS Pin 4 : 10 de la MEGA
  • GPS Pin 3 : 11 de la MEGA
  • GPS Pin 2 : GROUND de la MEGA
  • GPS Pin 1 : 3.3V de la MEGA

Ya conectado se mira asi:

Arduino IoT: Simple Tutorial GPS Titan3 Santiapps Marcio Valenzuela
Arduino IoT: Simple Tutorial GPS Titan3

El código viene de una muestra en la TinyGPS llamada test_with_gps_device que se puede encontrar en File > Examples > TinyGPS > Examples > test_with_ps_device.:

#include <SoftwareSerial.h>
#include <TinyGPS.h>
TinyGPS gps;
SoftwareSerial ss(10,11); //Rx from 
static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);
void setup(){
 Serial.begin(9600);
 Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
 Serial.println("by Mikal Hart");
 Serial.println();
 Serial.println("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum");
 Serial.println(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail");
 Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");
 ss.begin(9600);
}
void loop(){
 float flat, flon;
 unsigned long age, date, time, chars = 0;
 unsigned short sentences = 0, failed = 0;
 static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
 print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
 print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
 gps.f_get_position(&flat, &flon, &age);
 print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
 print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
 print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
 print_date(gps);
 print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
 print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
 print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
 print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
 print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
 print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
 print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);
 gps.stats(&chars, &sentences, &failed);
 print_int(chars, 0xFFFFFFFF, 6);
 print_int(sentences, 0xFFFFFFFF, 10);
 print_int(failed, 0xFFFFFFFF, 9);
 Serial.println();
 smartdelay(1000);
}
static void smartdelay(unsigned long ms){
 unsigned long start = millis();
 do {
 while (ss.available())
 gps.encode(ss.read());
 } while (millis() - start < ms);
}
static void print_float(float val, float invalid, int len, int prec){
 if (val == invalid){
 while (len-- > 1)
 Serial.print('*');
 Serial.print(' ');
 }else{
 Serial.print(val, prec);
 int vi = abs((int)val);
 int flen = prec + (val < 0.0 ? 2 : 1); // . and -
 flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
 for (int i=flen; i<len; ++i)
 Serial.print(' ');
 }
 smartdelay(0);
}
static void print_int(unsigned long val, unsigned long invalid, int len){
 char sz[32];
 if (val == invalid)
 strcpy(sz, "*******");
 else
 sprintf(sz, "%ld", val);
 sz[len] = 0;
 for (int i=strlen(sz); i<len; ++i)
 sz[i] = ' ';
 if (len > 0) 
 sz[len-1] = ' ';
 Serial.print(sz);
 smartdelay(0);
}
static void print_date(TinyGPS &gps){
 int year;
 byte month, day, hour, minute, second, hundredths;
 unsigned long age;
 gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
 if (age == TinyGPS::GPS_INVALID_AGE)
 Serial.print("********** ******** ");
 else{
 char sz[32];
 sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
 month, day, year, hour, minute, second);
 Serial.print(sz);
 }
 print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
 smartdelay(0);
}
static void print_str(const char *str, int len){
 int slen = strlen(str);
 for (int i=0; i<len; ++i)
 Serial.print(i<slen ? str[i] : ' ');
 smartdelay(0);
}

 

En el monitor serial saldrá algo así:

Arduino (IoT): Simple Tutorial GPS Glonass Titan 3 Santiapps Marcio Valenzuela
Arduino (IoT): Simple Tutorial GPS Glonass Titan 3

Esta es la misma informacion pero digerida o ‘parseada’ de cierta forma para ser mas legible.  Esto también se puede enviar a un servicio web para ‘plotear’ en un mapa o en una computadora con windows se puede usar esta aplicación para ver la data:

Este modulo GPS tiene grandes aplicaciones como rastrear vehículos, bienes de mucho valor, monitorear comportamiento de fauna o incluso programar Arduino Drones a volar de cierta ubicación a cierta otra ubicación!


		

Arduino (IoT): Simple Tutorial Medición de Corriente Sleep Mode AVR

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Medición de Corriente Sleep Mode AVR

En  un tutorial anterior vimos como medir la corriente consumida por la MCU.  El mismo método puede ser utilizado para medir el consumo de corriente de un proyecto completo, al insertar el medidor entre la fuente de poder.  Antes de llegar a ese ejemplo, el cual nos ayudara a medir el consumo energético de un proyecto para poder hacer cálculos de autonomía (por ejemplo cuanta energía tendríamos que producir y almacenar para un proyecto solar por ejemplo), vamos a ver como podemos ahorrar energía poniendo nuestra Arduino a dormir.

Requisitos:

  1. Computadora (mac)
  2. Arduino UNO
  3. Medidor de Voltaje/Corriente
  4. Battery Pack
  5. Breadboard
  6. Arduino IDE (https://www.arduino.cc/en/Main/Software)

El proyecto de nuestra Arduino es asi:


Esta vez cargaremos un sketch asi:


#include <avr/sleep.h>

/* Sleep Demo Serial
* -----------------
* Example code to demonstrate the sleep functions in an Arduino.
*
* use a resistor between RX and pin2. By default RX is pulled up to 5V
* therefore, we can use a sequence of Serial data forcing RX to 0, what
* will make pin2 go LOW activating INT0 external interrupt, bringing
* the MCU back to life
*
* there is also a time counter that will put the MCU to sleep after 10 secs
*
* NOTE: when coming back from POWER-DOWN mode, it takes a bit
* until the system is functional at 100%!! (typically <1sec)
*
* Copyright (C) 2006 MacSimski 2006-12-30
* Copyright (C) 2007 D. Cuartielles 2007-07-08 - Mexico DF
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

int wakePin = 2; // pin used for waking up
int sleepStatus = 0; // variable to store a request for sleep
int count = 0; // counter

void wakeUpNow() // here the interrupt is handled after wakeup
{
// execute code here after wake-up before returning to the loop() function
// timers and code using timers (serial.print and more...) will not work here.
// we don't really need to execute any special functions here, since we
// just want the thing to wake up
}

void setup()
{
pinMode(wakePin, INPUT);

Serial.begin(9600);

/* Now it is time to enable an interrupt. In the function call
* attachInterrupt(A, B, C)
* A can be either 0 or 1 for interrupts on pin 2 or 3.
*
* B Name of a function you want to execute while in interrupt A.
*
* C Trigger mode of the interrupt pin. can be:
* LOW a low level trigger
* CHANGE a change in level trigger
* RISING a rising edge of a level trigger
* FALLING a falling edge of a level trigger
*
* In all but the IDLE sleep modes only LOW can be used.
*/

attachInterrupt(0, wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
// wakeUpNow when pin 2 gets LOW
}

void sleepNow() // here we put the arduino to sleep
{
/* Now is the time to set the sleep mode. In the Atmega8 datasheet
* http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf on page 35
* there is a list of sleep modes which explains which clocks and
* wake up sources are available in which sleep mode.
*
* In the avr/sleep.h file, the call names of these sleep modes are to be found:
*
* The 5 different modes are:
* SLEEP_MODE_IDLE -the least power savings
* SLEEP_MODE_ADC
* SLEEP_MODE_PWR_SAVE
* SLEEP_MODE_STANDBY
* SLEEP_MODE_PWR_DOWN -the most power savings
*
* For now, we want as much power savings as possible, so we
* choose the according
* sleep mode: SLEEP_MODE_PWR_DOWN
*
*/
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here

sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin

/* Now it is time to enable an interrupt. We do it here so an
* accidentally pushed interrupt button doesn't interrupt
* our running program. if you want to be able to run
* interrupt code besides the sleep function, place it in
* setup() for example.
*
* In the function call attachInterrupt(A, B, C)
* A can be either 0 or 1 for interrupts on pin 2 or 3.
*
* B Name of a function you want to execute at interrupt for A.
*
* C Trigger mode of the interrupt pin. can be:
* LOW a low level triggers
* CHANGE a change in level triggers
* RISING a rising edge of a level triggers
* FALLING a falling edge of a level triggers
*
* In all but the IDLE sleep modes only LOW can be used.
*/

attachInterrupt(0,wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
// wakeUpNow when pin 2 gets LOW

sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP

sleep_disable(); // first thing after waking from sleep:
// disable sleep...
detachInterrupt(0); // disables interrupt 0 on pin 2 so the
// wakeUpNow code will not be executed
// during normal running time.

}

void loop()
{
// display information about the counter
Serial.print("Awake for ");
Serial.print(count);
Serial.println("sec");
count++;
delay(1000); // waits for a second

// compute the serial input
if (Serial.available()) {
int val = Serial.read();
if (val == 'S') {
Serial.println("Serial: Entering Sleep mode");
delay(100); // this delay is needed, the sleep
//function will provoke a Serial error otherwise!!
count = 0;
sleepNow(); // sleep function called here
}
if (val == 'A') {
Serial.println("Hola Caracola"); // classic dummy message
}
}

// check if it should go to sleep because of time
if (count >= 10) {
Serial.println("Timer: Entering Sleep mode");
delay(100); // this delay is needed, the sleep
//function will provoke a Serial error otherwise!!
count = 0;
sleepNow(); // sleep function called here
}
}

El código produce este resultado en el Serial Monitor:

Arduino IoT Simple Tutorial Medicion de Corriente AVR Sleep Mode by Santiapps Marcio Valenzuela
Arduino IoT Simple Tutorial Medicion de Corriente AVR Sleep Mode
Como podemos ver el codigo hace que la Arduino duerma luego de 10 segundos.  Es importante entender esto para que a la hora de medir la corriente sepamos que el consumo deberá bajar luego de 10 segundos para ver el ahorro.

Este código esta tomado del sitio Arduino.cc y es importante usar el Resistor 220Ohms entre el pin2 y el pin0(Rx). Subamos el código a la Arduino y luego hagamos las conexiones como hicimos anteriormente para medir la corriente.  La idea es medir la corriente mientras la Arduino esta despierta vs cuando esta dormida.

El resultado final esta aqui, sin embargo es igual a la anterior:


Pero luego de 10 segundos:


Como vemos el consumo baja de 46.5mA a 33.3mA.  Esto representa un ahorro del 28%.