Arduino IoT: Tutorial Simple Programar ATtiny85

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Simple Programar ATtiny85

 

En algun momento llegaremos a querer reducir el tamaño de nuestros proyectos por ejemplo para “wearables”, proyectos usados como vestimenta por la gente.

Aqui aprovechamos a programar la ATtiny85 via una Arduino UNO R3, aunque es posible obtener programadores standalone.

Esta es la ATTiny85 comparada con la ATmel y la Arduino UNO R3:

Arduino IoT: Tutorial Programming ATtiny85 via Arduino UNO R3 ArduinoISP by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial Programming ATtiny85 via Arduino UNO R3 ArduinoISP

Como podemos ver, no solo en tamaño sino que en componentes, la ATtiny85 tendrá la ventaja de consumo energético ademas de espacio.

Primero, tenemos que actualizar nuestro Arduino IDE para poder interface con una ATtiny85.  Esto lo hacemos en Preferences y Boards Manager:

https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json

Segundo, debemos cargar el sketch de ArduinoISP en el Sketchbook del Arduino IDE a la Arduino UNO R3 que vamos a usar como ISP.

Board: UNO > Tiny (Clock

Progr: AVRISPMkII > Arduino as ISP

Tercero, debemos hacer las conexiones entre la UNO R3 y la ATtiny85:

Arduino IoT: Tutorial Programming ATtiny85 via Arduino UNO R3 ArduinoISP by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial Programming ATtiny85 via Arduino UNO R3 ArduinoISP

Cuarto, vamos a cargar el sketch de Blink al ATtiny85 pero haciendo la siguiente modificación al codigo, cambiamos el pin 13 por el pin 0 porque la ATtiny85 no tiene tantos pines:

int ledpin = 0;
void setup() {
pinMode(ledpin, OUTPUT);
}
void loop() {
digitalWrite(ledpin, HIGH); 
delay(2500); 
digitalWrite(ledpin, LOW); 
delay(2500); 
}

Ahora cargamos el sketch Blink-modificado a la ATtiny85 modificando los parámetros de board y puerto para acceder a la tiny via la UNO.

Finalmente podemos ver los resultados:

OJO

Arduino IoT: Tutorial Programming ATtiny85 via Arduino UNO R3 ArduinoISP by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial Programming ATtiny85 via Arduino UNO R3 ArduinoISP
Advertisements

Arduino IoT: RTD PT 100 Sensores Industriales Parte II

Arduino IoT Arduino (IoT): Simple Tutorial de Infrarojo (IR) Receptor/Transmisor by Santiapps Marcio Valenzuela
Arduino IoT Arduino (IoT): Simple Tutorial de Infrarojo (IR) Receptor/Transmisor

Arduino (IoT): RTD PT 100 Sensores Industriales Parte II

 

Arduino IoT: RTD PT-100 Sensores Industriales by Santiapps Marcio Valenzuela
Arduino IoT: RTD PT-100 Sensores Industriales

En el tutorial anterior vimos como obtener resultados de un sensor industrial, PT100.  3 puntos importantes a recalcar:

  1. PT100 es un sensor muy sensible.  De hecho PT100 viene de “Pt” el símbolo para platino, que es un elemento usado por su confiabilidad.  Su resistencia varia de manera constante y confiable a lo largo de un gran rango de temperaturas.  Es esta resistencia la que medimos para obtener nuestros datos.
  2. La resistencia del circuito esta ligada al Voltage pero los voltajes son muy sensibles a ruido y podríamos confundir ruido de las lineas de transmisión con mediciones reales.  Por tanto usamos la corriente que es mucho mas estable y también esta relacionada a la R y V, según V=IR.  Para medir la corriente usamos un transmisor 4/20mA current loop.  Este aparato mide corriente y esa corriente es la que usamos para calcular la resistencia y convertirla a temperatura.
  3. Uno de los puntos mas importantes de cualquier medición es que las mediciones son instantáneas.  Es decir, se toman en un instante y muchas cosas pueden pasar entre un instante y otro.  Esto da como resultado varianzas que deben ser eliminadas.  Para ello es importante tomar varias muestras y obtener un promedio.  Existen cómputos estadísticos mas sofisticados que se pueden emplear para eliminar ruido y valores extremos pero por ahora veremos el mas sencillo, el promedio.

Realmente lo que debemos hacer es tomar varias muestras a lo largo del tiempo, almacenarlas y tomar un promedio de ellas. En programación podemos almacenar un gran grupo de datos en una estructura llamada arreglos, o arrays.  En Arduino definimos un array asi:

float analogVals[numReadings];

Aqui decimos que el array de nombre analogVals sera te valores tipo float y tendrá un cierto numero de elementos o items según la cantidad numReadings.

//Array vars
const unsigned int numReadings = 100;
float analogVals[numReadings];
unsigned int i = 0;

Aqui definimos el valor de numReadings en 100 y creamos un valor contador “i” iniciando con valor 0.  Este lo usaremos para incrementarlo cada vez que agreguemos un nuevo valor de temperatura al array y lo compararemos contra el numReadings de 100.  Al llegar a 100 valores, tomaremos el promedio.

analogVals[i] = f1;
if (i>=numReadings) {
//2. get average and go to test logic
float theAvgIs = average(analogVals,i);
//3. call logic
logicAction(theAvgIs);
i=0; //reset
} else {
i++;
}

Dentro del loop, almacenamos el valor del sensor, f1 y lo almacenamos en la primera posición del array analogVals[0] porque i empieza en 0.

Luego hacemos una prueba, si “i” ya llego a ser mayor o igual a 100, promediamos, de otra manera, solo le sumamos 1 a i, usando i++, y ahora i = 1 y volvemos al loop para tomar otra medicion.

Eventualmente cada vez que tomemos una medición y le sumemos 1 a i, i llegara a 100.  En ese momento ya hemos almacenado 100 valores en nuestro array y podemos hacer cálculos.

float average (float * array, int len){
float sum = 0L ;
for (int i = 0 ; i < len ; i++)
sum += array [i] ;
return ((float) sum) / len ;
}

En ese entonces llamamos esta función pasándole el array completo y su numero de elementos.  Esta función suma los valores del arreglo y los va almacenando en la variable sum.  Al final divide ese total entre len, el valor de items en el array para darnos un promedio y lo regresa al loop.

Regresando al loop ponemos ese valor en theAvgIs y lo pasamos a la función siguiente para tomar una decision sobre la lectura:

void logicAction(float thisIsIt){
if (thisIsIt > 20.0){
//its hot
Serial.println(“done…>20”);
Serial.println(thisIsIt);
} else {
//its cold
Serial.println(“done…<20”);
Serial.println(thisIsIt);
}
}

Aqui vemos que si el valor pasado es > a 20, esta caliente y si es menor a 20 esta frío.  En ese caso tomaríamos la accion en base a cada posibilidad, como cerrar válvulas, incrementar calor de la caldera etc.

Al final los resultados son:

Arduino IoT: RTD PT-100 Sensores Industriales by Santiapps Marcio Valenzuela
Arduino IoT: RTD PT-100 Sensores Industriales

Como podemos observar,  al calentar el sensor arriba de 20, la respuesta cambia y podríamos tomar las acciones necesarias.

Recordemos que hay otras mejoras; por ejemplo aquí esperamos a volver a llenar el array con 100 valores nuevos para obtener un nuevo promedio y poder comparar con lo deseado y tomar acciones.  Esperar 100 mediciones es bastante tiempo.  Podríamos ir llenando valores nuevos para reemplazar los mas viejos en el array, y tomar otro promedio al tener 10 nuevos y 90 viejos.  Así el promedio se actualizaría mas seguido y podríamos tomar mejores decisiones.

Arduino IoT: Tutorial Medidor de Agua Inteligente

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Medidor de Agua Inteligente Parte I

 

En este tutorial exploraremos mas sensores, pero aplicados.  En nuestro proyecto usamos un flujo metro construido a partir de un sensor Hall Effect para medir el flujo de agua por un conducto.

Se mira asi:

Arduino IoT: Tutorial Medidor de Flujo by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial Medidor de Flujo de Agua by Santiapps

El codigo:

byte statusLed = 13;
byte sensorInterrupt = 0; // 0 = digital pin 2
byte sensorPin = 2;
// El sensor hall-effect emite ~ 4.5 pulses/sec/litre/min 
float calibrationFactor = 4.5;
volatile byte pulseCount;
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long oldTime;
void setup(){

Serial.begin(38400);
// Usarmos una LED como salida
pinMode(statusLed, OUTPUT);
digitalWrite(statusLed, HIGH);
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, HIGH);
pulseCount = 0;
flowRate = 0.0;
flowMilliLitres = 0;
totalMilliLitres = 0;
oldTime = 0;

// Configuramos para que dispare con FALLING state (HIGH a LOW)
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}
void loop(){
if((millis() - oldTime) > 1000) { // Only process counters once per second
// Dishabilitamos el interrupt al calcular flujo y enviar
detachInterrupt(sensorInterrupt);
// Calculamos ms transcurridos desde la ultima ejecucion para escalar el resultado. Aplicamos el factor calibrationFactor para escalar el resultado en base al # de pulsos/sec de medición (litres/minute en este caso) proveniente del sensor
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
// Usar el tiempo de esta ejecucion porque deshabilitamos el interrupt por ende los millis() no funcionaran pero aun asi se retornara el valor justo antes que se deshabilito
oldTime = millis();
// Dividir el flujo en litres/minute por 60 para determinar cuantos L han pasado por el sensor en el intervalo de 1 sec y luego multiplicamos por 1000 para convertir a mL.
flowMilliLitres = (flowRate / 60) * 1000;
// Sumamos los mL pasados en este segundo al total cumulativo
totalMilliLitres += flowMilliLitres;
unsigned int frac;
// Imprimir el flujo para este intervalo de 1 segundo en litres / minute
Serial.print("Flujo: ");
Serial.print(int(flowRate)); // Imprimir el entero
Serial.print("."); // Imprimir el decimal
// Determinar la fraction. El 10 multiplicador nos da 1 decimal.
frac = (flowRate - int(flowRate)) * 10;
Serial.print(frac, DEC) ; // Imprimir la parte fraccional
Serial.print("L/min");
// Imprimir L fluidos en este segundo
Serial.print(" Liquido Fluido reciente: "); // Separador
Serial.print(flowMilliLitres);
Serial.print("mL/Sec");
// Imprimir cumulativo de L fluidos desde el inicio
Serial.print(" Cantidad total fluido: "); // Separador
Serial.print(totalMilliLitres);
Serial.println("mL");
// Resetear el pulse counter para iniciar de nuevo
pulseCount = 0;
// Habilitar el interrupt nuevamente
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}
}
void pulseCounter(){
// Incrementar pulse counter
pulseCount++;
}

Y la connexion es sencilla:

Arduino IoT: Tutorial Medidor de Flujo de Agua by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial Medidor de Flujo de Agua

Lo conectamos a una salida de agua como una bañera:

Arduino IoT: Tutorial Medidor de Flujo de Agua by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial Medidor de Flujo de Agua

Los resultados:

Arduino IoT: Tutorial Medidor de Flujo de Agua by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial Medidor de Flujo de Agua

Esto fue durante ~ 10 segundos.  Vamos a incorporar esto a nuestro proyecto de casa inteligente.

Arduino IoT: RTD PT 100 Sensores Industriales Parte I

Arduino IoT Arduino (IoT): Simple Tutorial de Infrarojo (IR) Receptor/Transmisor by Santiapps Marcio Valenzuela
Arduino IoT Arduino (IoT): Simple Tutorial de Infrarojo (IR) Receptor/Transmisor

Arduino (IoT): RTD PT 100 Sensores Industriales Parte I

Setup:

Arduino IoT: RTD PT-100 Sensores Industriales by Santiapps Marcio Valenzuela
Arduino IoT: RTD PT-100 Sensores Industriales

PT100 (blanco) ——–4/20mA (B)

Resistor A0-Tierra es 237Ω

Codigo:

int sensorValue = 0;
int temperature = 0;
int ReceivedByte = 0;
float f1 = 0;
float t1 = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("hi...");
}

void loop() {
  delay(1000);
  sensorValue = analogRead(A2);
  //Serial.println(sensorValue);
  /**
   current voltage(250 Ohm) ADC Temperature
 -----------------------------------------------------
 4 mA 1 V 205 -50 C
 20 mA 5 V 1023 +150 C
   **/
  // map the signals (multiplied by 10
  // to get decimal values, because map() doesn't work with floats)
  temperature=map(sensorValue,205,1023,-500,1500);
  f1 = temperature; // Float conversion
  t1 = f1/10.0; // dividing by 10
  // with one decimal value
  // Printing temperature value over serial port
  Serial.print(t1);
  Serial.print("n");

Resultados :

Arduino IoT: RTD PT-100 Sensores Industriales by Santiapps Marcio Valenzuela
Arduino IoT: RTD PT-100 Sensores Industriales

Arduino IoT: Tutorial sobre LM7805 como fuente de poder

Arduino IoT Arduino (IoT): Simple Tutorial de Infrarojo (IR) Receptor/Transmisor by Santiapps Marcio Valenzuela
Arduino IoT Arduino (IoT): Simple Tutorial de Infrarojo (IR) Receptor/Transmisor

Arduino (IoT): Tutorial LM7805 como fuente de poder

 

Muchas veces terminamos un prototipo y queremos llevarlo a la practica.  Es decir, queremos hacerlo funcionar en el ambiente para el cual fue diseñado.  El ejemplo típico en robótica es un carro, que luego de subir el codigo desde la compu al carro y probarlo mientras sigue conectado a la compu, queremos llevarlo a la calle.  En el caso de este robot para remover semillas, queremos conectarlo a su fuente de poder (baterías recargables) y llevarlo a la practica.

El problema es que necesitamos 5V para nuestros MCUs (a veces 3.3V) y tenemos combinaciones de baterías AA que nos dan 3V, 4.5V, 6V etc.  En este caso tenemos un par de baterías de alta capacidad de 3.7V cada una, ósea que tenemos 7.4V lo cual no podemos alimentar a nuestro MCU.

Entra el regulador de voltage, LM7805.  Este es uno de los componentes mas comunes en la electronica de hoy en dia.  A pesar que conectamos muchos electrónicos a la pared, de donde obtenemos 120VAC, nuestros electrónicos:

  • Celulares
  • Videojuegos portatiles
  • Tablets
  • Camaras digitales

Todos utilizan 5VDC.  Hay muchos otros componentes que reducen 120VAC a 5VDC y veremos eso en un tutorial mas adelante, pero por lo general siempre queremos tener 5VDC estables, y eso se obtiene a través de un regulador como este.

El diferencial de voltaje entre 7.4V y 5V se pierde como calor y a veces es necesario usar una fuente de disipación termica que en este caso no usamos, a pesar que los LM7805 traen una pequeña incorporada en su parte posterior que se ve de color gris-metal con un agujero en medio.  Por lo general para disipar voltajes mas altos se ocupa conectar el LM7805 a una placa mas grande.

Aquí vemos como los 7.4V son traspasados a 5V por el LM7805 y luego alimentados al mcu nano y al servo.  La LCD muestra el voltaje de la fuente de poder y lo vemos registrado como 4.99-5VDC.

Video

Es muy util poner uno de estos reguladores en un modulo aparte porque su uso sera muy frecuente.  El diagrama es así:

Arduino IoT: Tutorial LM7805 en Voltmeter by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial LM7805 en Voltmeter

Y el producto final se mira asi:

Este fue

Arduino IoT: Tutorial Uso de LM7805 Regulador de Voltaje by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial Uso de LM7805 Regulador de Voltaje

Aqui vemos la entrada a la derecha:

blanco: positivo & negro: negativo

Luego se pasa por el capacitor de 100uF, luego el LM7805 y finalmente el capacitor de 10uF.  Finalmente tenemos a la izquierda:

rojo: positivo & naranja: negativo

Aquí vemos un pack de baterias de 3.7V cada una en serie, para un total de 7.4V según muestra el medidor:

Arduino IoT: Tutorial Uso de LM7805 Regulador de Voltaje by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial Uso de LM7805 Regulador de Voltaje

Aqui vemos la medición directa del paquete de batería.  El regulador esta fuera de linea.

Arduino IoT: Tutorial Uso de LM7805 Regulador de Voltaje by Santiapps Marcio Valenzuela
Arduino IoT: Tutorial Uso de LM7805 Regulador de Voltaje

Finalmente vemos el regulador en acción, entre el pack de baterías y el medidor.  Aquí se ve el voltaje final regulado, el que podemos usar con seguridad en nuestros proyectos.

Los LM7805 se piden encontrar en muchos dispositivos electrónicos viejos que puede desarmar.

In: Entran 7.4V

GND: Tierra

Out: Salen 5.0V regulados

Arduino IoT: Simple Tutorial de Controlador Relay Remoto WiFi Parte 1

Arduino IoT Arduino (IoT): Simple Tutorial de Infrarojo (IR) Receptor/Transmisor by Santiapps Marcio Valenzuela
Arduino IoT Arduino (IoT): Simple Tutorial de Infrarojo (IR) Receptor/Transmisor

Arduino (IoT): Simple Tutorial de Controlador Relay Remoto WiFi Parte 1

 

Mucha gente me pide una manera de controlar remotamente un set de relays.  Asi que vamos a explorar el uso de una Arduino UNO + WiFi Shield.  Tenemos que correr un http server en la UNO (via la shield) para poder enviarle http requests a ese server con una IP fija en el router de Tigo que este ruteada a la IP fija interna de la UNO.  Esto requiere una UNO + WiFi shield + un router.

Basicamente vamos a hacer que la IP de Tigo en nuestro router sea dirigida a la computadora que queremos, en este caso la Arduino WiFi.  De esta manera cuando alguien visite la IP de nuestro router, sera dirigido a la Arduino WiFi:

Arduino IoT Tutorial Arduino WiFi Shield controlled relay by Santiapps Marcio Valenzuela
Arduino IoT Tutorial Arduino WiFi Shield controlled relay

Pasos

  1. Configurar Arduino WiFi Shield para conectarse a nuestra red Wifi ((https://www.youtube.com/watch?v=6izD9Gf5aSE)).  Los pasos básicamente son:
    1. Conectar WiFi shield a UNO
    2. PC, Soft, Normal
    3. Subir Blink Sketch
    4. PC-> UART & Serial Monitor 9600 NL & send $$$ (reply CMD)
    5. Switch to Carriage Return (Use ‘get everything’ to get config)
    6. ***set ip a 192.168.0.99 (and reserver it for this mac)
    7. set ip dhcp 0
    8. save
    9. reboot
    10. set wlan phrase…
    11. set wlan ssid…
    12. set wlan join 1
    13. save
    14. Reservar IP para MAC en Router
  2. Carga sketch de Servidor a Arduino UNO
    1. set back to Normal, PC, SS to upload server sketch to test browser access
    2. Agregar if else para reconocer name como comando para encender o apagar
  3. Configurar Router
    1. Router IP publico a IP privada de la WiFi shield

Ahora navegar a la ip e ingresar y recibir:


StFree memory: 1002
setPrompt hasnt been called
Starting
Free memory: 1002
setPrompt hasnt been called
Already joined network
MAC: 00:06:66:6f:33:a1
IP: 192.168.1.65
Netmask: 255.255.255.0
Gateway: 192.168.1.1
DeviceID: Wifly-WebServer
Ready
wifly.available! 🙂
Got GET request
Sent index page
wifly.available! 🙂
Unexpected: GET /favicon.ico HTTP/1.1
Sending 404
wifly.available! 🙂
Got POST
Sent greeting page

Arduino IoT Tutorial Arduino WiFi Shield controlled relay by Santiapps Marcio Valenzuela
Arduino IoT Tutorial Arduino WiFi Shield controlled relay
Arduino IoT Tutorial Arduino WiFi Shield controlled relay by Santiapps Marcio Valenzuela
Arduino IoT Tutorial Arduino WiFi Shield controlled relay

Ahora solo faltaría conectar la Arduino al relay y enviar el código a ella para controlar el relay.

Arduino (IoT) Video Serie Completa: Kit de Carro 4×4

Arduino Honduras Santiapps Marcio Valenzuela

Arduino (IoT) Video Serie Completa: Kit de Carro 4×4

Aqui tenemos la serie completa del video tutorial del Carro Inteligente 4×4:

  1. Chassis: http://santiapps.com/?p=2348
  2. Alambrado: http://santiapps.com/?p=2351
  3. Código Básico: http://santiapps.com/?p=2353
  4. Control IR: http://santiapps.com/?p=2379
  5. Control BLE: http://santiapps.com/?p=2387
  6. Auto-dirigido: http://santiapps.com/?p=2405&preview=true

Arduino (IoT) Video Serie: Kit de Carro Parte 6 (Auto-Dirigido)

Arduino Honduras Santiapps Marcio Valenzuela

Arduino (IoT) Video Serie: Kit de Carro Parte 6 (Auto-Dirigido)

Finalmente veremos como hacer un carro realmente inteligente.  Claro que hay mucho mas por hacer con un proyecto como este, pero espero que con este material tengan suficiente para poder arrancar.  Vamos a ver como agregar un sensor que le diga al carro que tan lejos esta de un obstáculo, hacer algunos cálculos para determinar cual es la mejor ruta a seguir y continuar.  Hay miles de maneras de hacer esto pero solo vamos a explorar una en detalle aqui y les dejare otra opción para su investigación [por ejemplo, agregar navegación GPS!].

Veamos las conexiones:

Arduino (IoT): Video Serie Smart Car 4WD Kit Auto-dirigido by Santiapps Marcio Valenzuela
Arduino (IoT): Video Serie Smart Car 4WD Kit Auto-dirigido

Si han llegado hasta este punto, lo mas dificil ya está hecho.  Solo falta desconectar los 2 cables que usábamos en la modalidad BT e IR para Rx/Tx datos porque ya no hay señales que transmitir.  Y el ultimo es quitar el jumper amarillo de la L293D.

El Jumper

Este jumper cuando esta interrumpido significa que la L293D usará la potencia de la fuente externa (las 4xAA) para los motores y debemos suplir una fuente alterna para la Arduino UNO.  Anteriormente solo usábamos 2 motores por lo cual no era necesario mas potencia pero ahora que usaremos 4 motores si es necesario.  Es decir, los 4 motores se usaran de manera mas continua debido a que el Arduino se continuara moviendo en distintas direcciones mientras decide cual es el mejor camino para avanzar.

Una vez removido el jumper, podemos conectar ambas fuentes de poder y listo!

Analicemos el código final:

Option 4WD
#include <AFMotor.h>
#include <NewPing.h>
#include <Servo.h>
// Los 2 pines del ultrasonico
#define TRIG_PIN A4 
#define ECHO_PIN A5 
#define MAX_DISTANCE 100
#define MAX_SPEED 180 // sets speed of DC motors
#define MAX_SPEED_OFFSET 20
// Distancias y velocidades maximas
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);
// Crear objetos para motores
AF_DCMotor motor1(1, MOTOR12_1KHZ); 
AF_DCMotor motor2(2, MOTOR12_1KHZ);
AF_DCMotor motor3(3, MOTOR12_1KHZ); 
AF_DCMotor motor4(4, MOTOR12_1KHZ);
//Iniciamos el objeto para servo
Servo myservo;
//Variable de estado de inicio falso
boolean goesForward=false;
int distance = 100;
int speedSet = 0;

void setup() {
//Iniciamos servo y tomamos 4 lecturas al frente
myservo.attach(9); 
 myservo.write(115); 
 delay(2000);
 distance = readPing();
 delay(100);
 distance = readPing();
 delay(100);
 distance = readPing();
 delay(100);
 distance = readPing();
 delay(100);
}

void loop() {
 int distanceR = 0;
 int distanceL = 0;
 delay(40);
 //Si distancia al frente<30, alto, retroceder, alto, medir derecha e izquierda
 if(distance<=30){
 moveStop();
 delay(100);
 moveBackward();
 delay(300);
 moveStop();
 delay(200);
 distanceR = lookRight();
 delay(200);
 distanceL = lookLeft();
 delay(200);
//Si distanciaR es mayor, girar derecha...
if(distanceR>=distanceL){
 turnRight();
 moveStop();
 }else{
 turnLeft();
 moveStop();
 }
 }else{
 moveForward();//Sino continuar...
 }
 distance = readPing();
}
//Mirar derecha
int lookRight(){
 myservo.write(50); 
 delay(500);
 int distance = readPing();
 delay(100);
 myservo.write(115); 
 return distance;
}
//Mirar izquierda
int lookLeft(){
 myservo.write(170); 
 delay(500);
 int distance = readPing();
 delay(100);
 myservo.write(115); 
 return distance;
 delay(100);
}
//Medir distancia
int readPing() { 
 delay(70);
 int cm = sonar.ping_cm();
 if(cm==0)
 {
 cm = 250;
 }
 return cm;
}
//Alto
void moveStop() {
 motor1.run(RELEASE); 
 motor2.run(RELEASE);
 motor3.run(RELEASE); 
 motor4.run(RELEASE);
 } 
//Mover al frente
void moveForward() {
if(!goesForward){
 goesForward=true;
 motor1.run(FORWARD); 
 motor2.run(FORWARD); 
 motor3.run(FORWARD); 
 motor4.run(FORWARD); 
 for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // Acelerar lentamente
 {
 motor1.setSpeed(speedSet);
 motor2.setSpeed(speedSet+MAX_SPEED_OFFSET);
 motor3.setSpeed(speedSet);
 motor4.setSpeed(speedSet+MAX_SPEED_OFFSET);
 delay(5);
 }
 }
}
//Retroceder
void moveBackward() {
 goesForward=false;
 motor1.run(BACKWARD); 
 motor2.run(BACKWARD); 
 motor3.run(BACKWARD); 
 motor4.run(BACKWARD); 
 for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // Acelerar lentamente
 {
 motor1.setSpeed(speedSet);
 motor2.setSpeed(speedSet+MAX_SPEED_OFFSET);
 motor3.setSpeed(speedSet);
 motor4.setSpeed(speedSet+MAX_SPEED_OFFSET);
 delay(5);
 }
}
//Girar derecha
void turnRight() {
 motor1.run(BACKWARD);
 motor2.run(BACKWARD); 
 motor3.run(FORWARD);
 motor4.run(FORWARD); 
 delay(300);
 motor1.run(BACKWARD);
 motor2.run(BACKWARD); 
 motor3.run(FORWARD);
 motor4.run(FORWARD); 
 delay(300);
 motor1.run(BACKWARD);
 motor2.run(BACKWARD); 
 motor3.run(FORWARD);
 motor4.run(FORWARD); 
 delay(300);
 motor1.run(FORWARD); 
 motor2.run(FORWARD); 
 motor3.run(FORWARD); 
 motor4.run(FORWARD); 
} 
//Girar Izquierda
void turnLeft() {
 motor1.run(FORWARD); 
 motor2.run(FORWARD); 
 motor3.run(BACKWARD);
 motor4.run(BACKWARD); 
 delay(300);
 motor1.run(FORWARD); 
 motor2.run(FORWARD); 
 motor3.run(BACKWARD);
 motor4.run(BACKWARD); 
 delay(300);
 motor1.run(FORWARD); 
 motor2.run(FORWARD); 
 motor3.run(BACKWARD);
 motor4.run(BACKWARD); 
 delay(300);
 motor1.run(FORWARD); 
 motor2.run(FORWARD);
 motor3.run(FORWARD); 
 motor4.run(FORWARD);
}

Segunda opción para 4WD (re-definir motores)

#include //add Adafruit Motor Shield library
#include //add Servo Motor library            
#include //add Ultrasonic sensor library

#define TRIG_PIN A0 // Pin A0 on the Motor Drive Shield soldered to the ultrasonic sensor
#define ECHO_PIN A1 // Pin A1 on the Motor Drive Shield soldered to the ultrasonic sensor
#define MAX_DISTANCE 300 // sets maximum useable sensor measuring distance to 300cm
#define MAX_SPEED 160 // sets speed of DC traction motors to 150/250 or about 70% of full speed - to get power drain down.
#define MAX_SPEED_OFFSET 40 // this sets offset to allow for differences between the two DC traction motors
#define COLL_DIST 30 // sets distance at which robot stops and reverses to 30cm
#define TURN_DIST COLL_DIST+20 // sets distance at which robot veers away from object
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); // sets up sensor library to use the correct pins to measure distance.

AF_DCMotor leftMotor1(1, MOTOR12_1KHZ); // create motor #1 using M1 output on Motor Drive Shield, set to 1kHz PWM frequency
AF_DCMotor leftMotor2(2, MOTOR12_1KHZ); // create motor #2, using M2 output, set to 1kHz PWM frequency
AF_DCMotor rightMotor1(3, MOTOR34_1KHZ);// create motor #3, using M3 output, set to 1kHz PWM frequency
AF_DCMotor rightMotor2(4, MOTOR34_1KHZ);// create motor #4, using M4 output, set to 1kHz PWM frequency
Servo myservo;  // create servo object to control a servo 

int leftDistance, rightDistance; //distances on either side
int curDist = 0;
String motorSet = "";
int speedSet = 0;

//-------------------------------------------- SETUP LOOP ----------------------------------------------------------------------------
void setup() {
  myservo.attach(10);  // attaches the servo on pin 10 (SERVO_1 on the Motor Drive Shield to the servo object 
  myservo.write(90); // tells the servo to position at 90-degrees ie. facing forward.
  delay(1000); // delay for one seconds
 }
//------------------------------------------------------------------------------------------------------------------------------------

//---------------------------------------------MAIN LOOP ------------------------------------------------------------------------------
void loop() {
  myservo.write(90);  // move eyes forward
  delay(90);
  curDist = readPing();   // read distance
  if (curDist < COLL_DIST) {changePath();} // if forward is blocked change direction moveForward(); // move forward delay(500); } //------------------------------------------------------------------------------------------------------------------------------------- void changePath() { moveStop(); // stop forward movement myservo.write(36); // check distance to the right delay(500); rightDistance = readPing(); //set right distance delay(500); myservo.write(144); // check distace to the left delay(700); leftDistance = readPing(); //set left distance delay(500); myservo.write(90); //return to center delay(100); compareDistance(); } void compareDistance() // find the longest distance { if (leftDistance>rightDistance) //if left is less obstructed 
  {
    turnLeft();
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    turnRight();
  }
   else //if they are equally obstructed
  {
    turnAround();
  }
}


//-------------------------------------------------------------------------------------------------------------------------------------

int readPing() { // read the ultrasonic sensor distance
  delay(70);   
  unsigned int uS = sonar.ping();
  int cm = uS/US_ROUNDTRIP_CM;
  return cm;
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveStop() {leftMotor1.run(RELEASE); leftMotor2.run(RELEASE); rightMotor1.run(RELEASE); rightMotor2.run(RELEASE);}  // stop the motors.
//-------------------------------------------------------------------------------------------------------------------------------------
void moveForward() {
    motorSet = "FORWARD";
    leftMotor1.run(FORWARD);      // turn it on going forward
    leftMotor2.run(FORWARD);      // turn it on going forward
    rightMotor1.run(FORWARD);     // turn it on going forward
    rightMotor2.run(FORWARD);     // turn it on going forward
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    leftMotor1.setSpeed(speedSet);
    leftMotor2.setSpeed(speedSet);
    rightMotor1.setSpeed(speedSet); 
    rightMotor2.setSpeed(speedSet);
    delay(5);
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveBackward() {
    motorSet = "BACKWARD";
    leftMotor1.run(BACKWARD);     // turn it on going backward
    leftMotor2.run(BACKWARD);     // turn it on going backward
    rightMotor1.run(BACKWARD);    // turn it on going backward
    rightMotor2.run(BACKWARD);    // turn it on going backward
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    leftMotor1.setSpeed(speedSet);
    leftMotor2.setSpeed(speedSet);
    rightMotor1.setSpeed(speedSet); 
    rightMotor2.setSpeed(speedSet); 
    delay(5);
  }
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnRight() {
  motorSet = "RIGHT";
  leftMotor1.run(FORWARD);      // turn motor 1 forward
  leftMotor2.run(FORWARD);      // turn motor 2 forward
  rightMotor1.run(BACKWARD);    // turn motor 3 backward
  rightMotor2.run(BACKWARD);    // turn motor 4 backward
  rightMotor1.setSpeed(speedSet+MAX_SPEED_OFFSET);      
  rightMotor2.setSpeed(speedSet+MAX_SPEED_OFFSET);     
  delay(1500); // run motors this way for 1500        
  motorSet = "FORWARD";
  leftMotor1.run(FORWARD);      // set both motors back to forward
  leftMotor2.run(FORWARD);
  rightMotor1.run(FORWARD);
  rightMotor2.run(FORWARD);      
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnLeft() {
  motorSet = "LEFT";
  leftMotor1.run(BACKWARD);      // turn motor 1 backward
  leftMotor2.run(BACKWARD);      // turn motor 2 backward
  leftMotor1.setSpeed(speedSet+MAX_SPEED_OFFSET);     
  leftMotor2.setSpeed(speedSet+MAX_SPEED_OFFSET);    
  rightMotor1.run(FORWARD);     // turn motor 3 forward
  rightMotor2.run(FORWARD);     // turn motor 4 forward
  delay(1500); // run motors this way for 1500  
  motorSet = "FORWARD";
  leftMotor1.run(FORWARD);      // turn it on going forward
  leftMotor2.run(FORWARD);      // turn it on going forward
  rightMotor1.run(FORWARD);     // turn it on going forward
  rightMotor2.run(FORWARD);     // turn it on going forward
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnAround() {
  motorSet = "RIGHT";
  leftMotor1.run(FORWARD);      // turn motor 1 forward
  leftMotor2.run(FORWARD);      // turn motor 2 forward
  rightMotor1.run(BACKWARD);    // turn motor 3 backward
  rightMotor2.run(BACKWARD);    // turn motor 4 backward
  rightMotor1.setSpeed(speedSet+MAX_SPEED_OFFSET);      
  rightMotor2.setSpeed(speedSet+MAX_SPEED_OFFSET);
  delay(1700); // run motors this way for 1700
  motorSet = "FORWARD";
  leftMotor1.run(FORWARD);      // set both motors back to forward
  leftMotor2.run(FORWARD);
  rightMotor1.run(FORWARD);
  rightMotor2.run(FORWARD);      
}  

Arduino (IoT): Stepper para abrir puertas con L298N

Arduino Honduras Santiapps Marcio Valenzuela

Simple Tutorial Stepper Motor con L298N

 

Vamos a usar un stepper para abrir una puerta.  Idealmente usaríamos un mecanismo mas sofisticado como un brazo  tipo tijera para abrir una puerta, pero en este caso usamos un simple hilo para enrollarlo con un stepper.

Requisitos:

  1. Computadora (mac)
  2. Arduino UNO o equivalente.
  3. L298N driver board
  4. Stepper 12V & 400mA bi-polar (30Ohm por fase)
  5. Battery pack de 6 batteries AA en serie
  6. 6 baterias AA
  7. Arduino IDE (https://www.arduino.cc/en/Main/Software)

El H-bridge que usaremos es el siguiente.  Es capaz de suplir hasta 2A pero nuestro motor solo demandara 400mA:

Arduino IoT Simple Tutorial Stepper Motors L298N Santiapps.com Marcio Valenzuela
Arduino IoT Simple Tutorial Stepper Motors L298N

El motor es el siguiente:

Arduino IoT Simple Tutorial Stepper Motors L298N Santiapps.com Marcio Valenzuela
Arduino IoT Simple Tutorial Stepper Motors L298N Santiapps.com Marcio Valenzuela

Hacemos nuestras conexiones así:

Arduino IoT Simple Tutorial Stepper Motors L298N Santiapps.com Marcio Valenzuela
Arduino IoT Simple Tutorial Stepper Motors L298N

El alambrado es basicamente asi:

L298N——————————

Out1 & Out2 ————-2 cables de 1 winding del stepper

Out3 & Out4 ————-2 cables del otro winding del stepper (bi-polares solo tienen 4 cables)

In1,In2,3&4  ————- Pines digitales 8,9,10 & 11 de la Arduino UNO

Vcc ———————— + de 9V

GND ———————- GND de Arduino UNO

5V ————————- 5V de Arduino UNO

[GND de Arduino UNO a – de 9V]

Al final se mira asi:

Arduino IoT Simple Tutorial Stepper Motors L298N Santiapps.com Marcio Valenzuela
Arduino IoT Simple Tutorial Stepper Motors L298N

Y con la Arduino UNO:

Arduino IoT Simple Tutorial Stepper Motors L298N Santiapps.com Marcio Valenzuela
Arduino IoT Simple Tutorial Stepper Motors L298N

Y el coding es el siguiente:

#include <Stepper.h>
const int stepsPerRevolution = 200;
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
void setup() {
myStepper.setSpeed(60);
}
void loop() {
myStepper.step(stepsPerRevolution);
}

 

Aqui esta el video!

 

Arduino (IoT) Video Serie: Kit de Carro Parte 5 (BT)

Arduino Honduras Santiapps Marcio Valenzuela

Arduino (IoT) Video Serie: Kit de Carro Parte 5 (BT)

En este caso usaremos un HM10, un modulo BLE (Bluetooth de baja energía) que es ideal para proyectos como este por su bajo consumo energético.  Antes de hacer funcionar el BLE, vamos a darle poder desde la Arduino 5V/GND para hacer parpadear la LED roja alrededor de 1 vez por segundo.  Esto significa que el BLE esta listo para conectarse.  Podemos verificar esto con un teléfono que tenga BLE y descubra el modulo, por lo general un Android es ideal o una laptop.  Para un iPhone es mejor usar una app como BLE Scanner u otras similares.

Estos BLE pueden utilizar 5V pero para transmitir ocupan 3.3V por lo cual es necesario hacer un divisor de voltaje con 1Ω y 2Ω para conectar al Tx de la Arduino.  En el video vemos las conexiones, como descubrir el modulo con un celular y como interactuar con el via Arduino usando el código.

Este es el código final:

#include "SoftwareSerial.h"// import the serial library
#include "AFMotor.h"

AF_DCMotor motor1(1, MOTOR12_64KHZ); // create motor #1, 64KHz pwm
AF_DCMotor motor2(2, MOTOR12_64KHZ); // create motor #2, 64KHz pwm
AF_DCMotor motor3(3, MOTOR12_64KHZ); // create motor #2, 64KHz pwm
AF_DCMotor motor4(4, MOTOR12_64KHZ); // create motor #2, 64KHz pwm

SoftwareSerial btserial(10, 2); // RX, TX
char c=' ';
boolean NL = true;

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  btserial.begin(9600);
    
  motor1.setSpeed(200);     // set the speed to 200/255
  motor2.setSpeed(200);     // set the speed to 200/255
  motor3.setSpeed(200);     // set the speed to 200/255
  motor4.setSpeed(200);     // set the speed to 200/255

}

void loop() {
  // Leer bluetooth, si es 1, Adelante...
  if (btserial.available()){
    c=btserial.read();
    Serial.write(c);

    if(c=='1'){   // if number 1 pressed ....
        Serial.write("Forward");
      forward();
    }
    if(c=='2'){// if number 2 pressed ....
        Serial.write("Backward");

      backward();
    }
    if(c=='3'){// if number 3 pressed ....
        Serial.write("Left");

      left();
    }
    if(c=='4'){// if number 4 pressed ....
        Serial.write("Right");
      right();
    }
    if(c=='5'){// if number 5 pressed ....
        Serial.write("BRAKE");
      brake();
    }
}

  // Serial Monitor Write BT
    if (Serial.available()){
        c = Serial.read();
      
        // do not send line end characters to the HM-10
        if (c!=10 & c!=13 ) {  
             btserial.write(c);
        }
 
        // If there is a new line print the ">" character.
        if (NL) { Serial.print("rn>");  NL = false; }
        Serial.write(c);
        if (c==10) { NL = true; }
    }  

}

void forward(){
  Serial.println("running forward");
  motor1.run(FORWARD);   
  motor2.run(FORWARD);
  motor3.run(FORWARD);   
  motor4.run(FORWARD);
  delay(3000);  
  brake();
}
void backward(){
  Serial.println("running backward");
  motor1.run(BACKWARD);   
  motor2.run(BACKWARD);
  motor3.run(BACKWARD);   
  motor4.run(BACKWARD);
  delay(3000);  
  brake();   
}

void left(){
  motor3.run(FORWARD);   
  motor2.run(BACKWARD);   
}
void right(){
  motor4.run(FORWARD);    
  motor1.run(FORWARD);     
}

void brake(){
  motor1.run(RELEASE);    
  motor2.run(RELEASE);    
  motor3.run(RELEASE);    
  motor4.run(RELEASE);      
}