viernes, 30 de noviembre de 2018

Medir distancia mediante ESP32 y enviar al puerto serie


int EchoPin = 13;
int TriggerPin = 12;

void setup() {
   Serial.begin(115200);
   pinMode(TriggerPin, OUTPUT);
   pinMode(EchoPin, INPUT);
}

void loop() {
   int cm = ping(TriggerPin, EchoPin);
   Serial.print("Distancia: ");
   Serial.println(cm);
   delay(1000);
}

int ping(int TriggerPin, int EchoPin) {
   long duration, distanceCm;
  
   digitalWrite(TriggerPin, LOW);  //para generar un pulso limpio ponemos a LOW 4us
   delayMicroseconds(4);
   digitalWrite(TriggerPin, HIGH);  //generamos Trigger (disparo) de 10us
   delayMicroseconds(10);
   digitalWrite(TriggerPin, LOW);
  
   duration = pulseIn(EchoPin, HIGH);  //medimos el tiempo entre pulsos, en microsegundos
  
   distanceCm = duration * 10 / 292/ 2;   //convertimos a distancia, en cm
   return distanceCm;
}

ESP32 con matriz 16x16 dos imagenes que cambian usando millis() con un retardo de 1000 ms


//salidas que se van a utilizar
#define dataPin 13
#define clockPin 12
#define latchPin 14

uint16_t dato1[] = {
  0xFFFF,
  0x8001,
  0xBFFD,
  0xA005,
  0xAFF5,
  0xA815,
  0xABD5,
  0xAA55,
  0xAA55,
  0xABD5,
  0xA815,
  0xAFF5,
  0xA005,
  0xBFFD,
  0x8001,
  0xFFFF
};

uint16_t dato2[] = {
  0x0000,
  0x7FFE,
  0x4002,
  0x5FFA,
  0x500A,
  0x57EA,
  0x542A,
  0x55AA,
  0x55AA,
  0x542A,
  0x57EA,
  0x500A,
  0x5FFA,
  0x4002,
  0x7FFE,
  0x0000
};

byte i, j;
byte fi_L, fi_H;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  for (i = 0; i < 16; i++) dato1[i] ^= 0xFFFF;
  for (i = 0; i < 16; i++) dato2[i] ^= 0xFFFF;
}

void loop() {
  muestra (dato1);
  //delay(1000);
  muestra (dato2);
  //delay(1000);
}

void muestra (uint16_t *matriz) {
  double t_inicio;
  unsigned int retardo=1000;
  uint16_t aux;
  byte enviar;
  uint16_t n_fila;
  int n;
  t_inicio = millis();
  while (millis()<(t_inicio+retardo)) {
    n_fila = 1;
    for (i = 0; i < 16; i++, n_fila <<= 1) {
      fi_L = n_fila & 0xFF;
      fi_H = (n_fila >> 8) & 0xFF;
      digitalWrite(latchPin, 0);
      shiftOut(dataPin, clockPin, LSBFIRST, fi_L);
      shiftOut(dataPin, clockPin, LSBFIRST, fi_H);
      aux = matriz[i];
      enviar = aux & 0x00ff;
      shiftOut(dataPin, clockPin, LSBFIRST, enviar);
      enviar = (aux >> 8) & 0x00ff;
      shiftOut(dataPin, clockPin, LSBFIRST, enviar);
      digitalWrite(latchPin, 1);
    }
  }
}

jueves, 29 de noviembre de 2018

ESP32 con la matriz de 16x16. Mensaje HOLA.

//salidas que se van a utilizar
//pongo las 5 seguidas para que sea más sencillo conectarlas
//VCC
//GND
#define dataPin 13
#define clockPin 12
#define latchPin 14

/*
 * poniendo el array en uint16_t y colocando la información en columnas en vez de en filas sería más facil crear mensajes largos
 */
//array en el que se va a contener toda la informacin de filas
uint32_t dato[] = {
  0xCC7183F0,
  0xCCF983F0,
  0xCDDD8330,
  0xCD8D8330,
  0xCD8D8330,
  0xCD8D8330,
  0xCD8D8330,
  0xFD8D83F0,
  0xFD8D83F0,
  0xCD8D8330,
  0xCD8D8330,
  0xCD8D8330,
  0xCD8D8330,
  0xCDDD8330,
  0xCCF9FB36,
  0xCC71FB36
};//informacion de las columnas

byte i, j;
byte fi_L, fi_H;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  for (i = 0; i < 16; i++) dato[i] ^= 0xFFFFFFFF; //invierto todos los bits porque las columnas van a los cátodos.
  //si se cambia por uint16_t habría que cambiar esto de la inversión
}

void loop() {
  muestra (dato,32,1000);//(matriz, ancho de la matriz, numero de repeticiones) cuanto mayor sea el numero de repeticiones más tardará en pasar a la siguiente columna.
  uint32_t limpia[16];
  for (int i=0;i<16;i++){
    limpia[i]=0xFFFFFFFF;
  }
  muestra(limpia,32,10);
  delay(1000);
}

void muestra (uint32_t *matriz, int ancho, unsigned int numero_rep) {//puesto que es una variable global podría usar dato[]
  double t_inicio;
  uint32_t aux;
  byte enviar;
  uint16_t n_fila;
  //unsigned int n;
  for (j = 0; j < ancho - 16; j++) {//empiezo en 32 porque es la anchura total (para empezar por el extremo izquierdo termino en 32-16 porque la anchura de la matriz de puntos es 16
    for (int n = 0; n < numero_rep; n++) {//es una espera (va a repetir la información hasta saltar a la siguiente columna. Por eso no se hace nada con n.

      //se posiciona la variable que indica el numero de fila en la primera fila (como es de 16 bits, se carga en una variable uint16_n)
      n_fila = 1;

      //como tiene 16 filas se van a enviar de una en una
      for (i = 0; i < 16; i++, n_fila <<= 1) {//lo de rotar 1 bit a la izquierda es para que pase a la siguiente columna

        //se extraen los bytes de menor y menor peso

        //el de menor peso mediante una AND con 0000 0000 1111 1111
        fi_L = n_fila & 0xFF;

        //el de mayor peso mediante la misma AND pero con la variable n_fila desplazada 1 byte hacia la derecha
        fi_H = (n_fila >> 8) & 0xFF;

        //se prepara para recibir datos
        digitalWrite(latchPin, 0);

        //se envía la información de la fila (lógica positiva, una fila de cada vez)
        shiftOut(dataPin, clockPin, LSBFIRST, fi_L);
        shiftOut(dataPin, clockPin, LSBFIRST, fi_H);

        //se envía la información de la columna (lógica negativa, por eso se invierte la matriz en setup()

        //se posiciona en el primer bit desplazando el ancho total - 16 - i (que va a variar) y se carga en una variable de tipo uint32_n (como la matriz)
        aux = matriz[i] >> (ancho - 16 - j);
        //se cogen el byte de menor peso (operación AND con 0000 0000 1111 1111)
        enviar = aux & 0x00ff;
        //se envía el byte de menor peso que se había extraido
        shiftOut(dataPin, clockPin, LSBFIRST, enviar);
        //se extrae el segundo byte porque el dato se va a desplazar 1 byte a la derecha (el resto es como el anterior)
        enviar = (aux >> 8) & 0x00ff;
        shiftOut(dataPin, clockPin, LSBFIRST, enviar);

        //se desactiva la recepción de datos y por lo tanto los va a mostrar
        digitalWrite(latchPin, 1);
      }
    }//cuando ha repetido el numero de veces seleccionado, se pasa a la siguiente columna.
  }
}

miércoles, 15 de abril de 2015

How to use 315Mhz RF transmitter and receiver modules with arduino

http://www.buildcircuit.com/how-to-use-rf-module-with-arduino/


Hay que descargar la librería que utilizan en el ejemplo: http://www.pjrc.com/teensy/td_libs_VirtualWire.html

Pongo los códigos fuente:

emisorhttps://gist.githubusercontent.com/buildcircuit/5907275/raw/gistfile1.ino
/*
SimpleSend
This sketch transmits a short text message using the VirtualWire library
connect the Transmitter data pin to Arduino pin 12
*/
#include <VirtualWire.h>
void setup()
{
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
}
void loop()
{
send("Hello there");
delay(1000);
}
void send (char *message)
{
vw_send((uint8_t *)message, strlen(message));
vw_wait_tx(); // Wait until the whole message is gone
}

receptor: https://gist.githubusercontent.com/buildcircuit/5907280/raw/gistfile1.ino
/*
SimpleReceive
This sketch displays text strings received using VirtualWire
Connect the Receiver data pin to Arduino pin 11
*/
#include <VirtualWire.h>
byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
void setup()
{
Serial.begin(9600);
Serial.println("Device is ready");
// Initialize the IO and ISR
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver
}
void loop()
{
if (vw_get_message(message, &messageLength)) // Non-blocking
{
Serial.print("Received: ");
for (int i = 0; i < messageLength; i++)
{
Serial.write(message[i]);
}
Serial.println();
}
}

martes, 3 de junio de 2014

SD Card Socket Modlue +2.8" Inch TFT Touch Screen Development Board For Arduino


De momento pongo la copia de seguridad del CD que le acompañaba. parece que es elentorno de programación de arduino adaptado para este dispositivo y que solo funciona en windows. Al menos el ejecutable es para windows, deduzco que las librerías que le acompañan son para el mismo sistema operativo y que por lo tanto desde otros sistemas operativos no va a funcionar.

El enlace al fichero es: https://drive.google.com/file/d/0B779vDAuKIBKSWJsMEY0OE0yZ3M/edit?usp=sharing


sábado, 10 de mayo de 2014

2088RGB-5 (Matriz RGB de 8x8 de ánodo común sin resistencias)

Imagen de las conexiones del dispositivo:
Se puede ver que la patilla nº 1 es la de la esquina inferior derecha.
Alguien (https://www.flickr.com/photos/madworm_de/2997547008/sizes/o/in/photostream/) ha puesto esto en internet:
Aunque no son idénticos, es facil comprobar si está bien o mal. Mediante un polímetro se localiza el ánodo y el resto solo es saber de que color es cada grupo.
Lo importante viene ahora. Hay varias soluciones para enviar los datos.
  • Enviar los 32 datos vía serie.
  • Enviar 4 grupos de datos vía serie (uno para cada color y otro para en ánodo).
  • Enviar 4 grupos de 8 bits.
El más lógico parece el último porque sería más rápido, solo serían necesarios 4 buffers (no sería necesario poner registros de desplazamiento). A cambio, se necesitan más salidas: 8 bits para los datos y 4 para las direcciones (que podrían quedarse en 2 si se multiplexan). Lo de multiplexar salidas sería recomendable en caso de que no disponer de suficientes salidas. A cambio, no se podría enviar el mismo dato a todas a la vez (por ejemplo encender o apagar todo a la vez).

En todos los casos se hace necesario fabricar un circuito impreso y eso lleva a una nueva duda. Poner resistencias en los cátodos o en el ánodo.
Ventajas e inconvenientes de cada una de las soluciones (no voy a tener en cuenta la económica porque es una miseria):
  • Más resistencias => Circuito impreso más grande
  • Más resistencias => Mayor facilidad para conectar los dispositivos al poder pasar las pistas por debajo de las resistencias.
  • Más resistencias => Más luz que si tienen una común.
  • Más resistencias => Más control de la corriente de cada led (tienen distintas corrientes/tensiones de funcionamiento).
  • Resistencia común => Es posible que los colores azul y verde no se enciendan si se activan con el rojo porque funciona con menos tensión (no lo he comprobado)
Después de valorar todo, creo que es mejor utilizar 12 salidas del arduino (no multiplexar) y poner 24 resistencias.
Falta localizar los circuitos integrados con 8 básculas tipo D adecuados y calcular las resistencias.
De momento ya he expuesto las ideas. Cuando vuelva a hacer algo lo publicaré.
He encontrado algo que podría valer: 74XX373
  • Tiene un precio razonable.
  • A pesar de ser de la serie 74 es un CMOS.
    • Tiene un consumo reducido.
    • Tiene un buen margen de tensiones de alimentación.
    • Puede suministrar perfectamente la corriente que precisan los LEDs.
  • Cumple sobradamente con las carácterísticas (le sobra la salida triestado pero es facil inhabilitarla poniendo Output Enable a cero)
  • El patillaje es un poco complejo para el circuito impreso porque se llenaría de cruces por la configuración de entradas/salidas.
Hay un datasheet en: http://www.harrisonelectronics.co.uk/datasheets/MC74HC373ADW.pdf
Y en su página principal hay datasheets de muchos componentes corrientes (muy utilizados): Harrison Electronics

Creo que ya está: http://www.fairchildsemi.com/ds/74/74VHC573.pdf
http://pinout-circuits-images.dz863.com/6/CD74HC573.jpg
CD74HC573 pinout from datasheet
Se puede ver que a un lado están  las entradas y a otro las salidas. Lo mismo que en el 373 hay que poner la patilla 1 a masa para que esté siempre activado (no se necesita el triestado).

Para el cálculo de las resistencias he encontrado un problema: potencia máxima 150 mw. Teniendo en cuenta que:

  • LED Rojo: 2,2V/50mA=110mw
  • LED Verde: 3,3V/50mA=165mw
  • LED Azul: 3,3V/50mA=165mw
No se si 150mw se refiere a la potencia máxima que soporta cada conjunto o cada led individual.
En el caso de que sea el primero (lo más probable por la refrigeración) habría que poner una resistencia común o evitar encender los tres a la vez.
Si se hace pasar 15 mA por LED, no se superaría la potencia máxima aunque se activaran los 3 simultáneamente.
Los valores serían:

  • R: (5V-2,2V)/15mA=187 Ohm
  • G: (5V-3,3V)/15mA=113 Ohm
  • B: (5V-3,3V)/15mA=113 Ohm
  • Valores normalizados (E24 - 5%):
    • R: 150-200=> 200 Ohm
    • G=B: 110-130 => 110 Ohm
  • Valores normalizados (E12 - 10%):
    • R: 150-270 => 150 Ohm -> I=2,8V/150=18,7mA
    • G-B: 100-150 => 100 Ohm -> I=1,7/100=17mA
  • Potencias para E12:
    • R: 2,8V*18,7mA=52,36mw
    • G-B:1,7V*17mA=28.9mw
    • Potencia TOTAL=52,36+28,9+28,9=110,16mw
Incluso poniendo resistencias muy distintas a las inicialmente calculadas estaría lejos de la potencia máxima.
Falta diseñar la placa de circuito impreso, a ser posible de una cara. Eso llevará más tiempo...

lunes, 31 de marzo de 2014

Juego de luces sencillo para matriz 16x16

Se va acercando desde las 4 esquinas hacia el centro y cuando llega se enciende entero:

Código fuente:

//salidas que se van a utilizar
int latchPin = 8; //patilla LT
int clockPin = 12; //patilla SK
int dataPin = 11; //patilla RI1
//array en el que se va a contener toda la informacin de filas y columnas
byte dato[4];
byte i;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  dato[0]=0xFF;
  dato[1]=0xFF;
  dato[2]=0x00;
  dato[3]=0x00;
  envia_datos(dato);
}

void envia_datos(byte *matrix) {
  digitalWrite(latchPin, 0);
  for (byte i=4; i>2; i--) shiftOut(dataPin, clockPin, LSBFIRST, matrix[i-1]);
  for (byte i=2; i>0; i--) shiftOut(dataPin, clockPin, MSBFIRST, matrix[i-1]);
  digitalWrite(latchPin, 1);
  delay(500);
}

void loop() {
  dato[3]=0x01;
  dato[2]=0x80;
  dato[1]=0x7F;
  dato[0]=0xFE;
  envia_datos(dato);
  delay(500);
 
  for (i=0;i<6;i++){
    dato[3]*=2;  
    bitClear(dato[3],7);
    dato[2]/=2;
    bitClear(dato[2],0);
    dato[1]>>=1;
    bitSet(dato[1], 7);
    dato[0]<<=1;
    bitSet(dato[0], 0);
  envia_datos(dato);
  delay(500);  
  }
  dato[0]=0x00;
  dato[1]=0x00;
  dato[2]=0xFF;
  dato[3]=0xFF;
  envia_datos(dato);
 
  delay(500);
 
  dato[0]=0xFF;
  dato[1]=0xFF;
  dato[2]=0x00;
  dato[3]=0x00;
  envia_datos(dato);
 
  delay(500);

}