Apunts

Aquest apartat conte notes sobre alguns dels projectes sueltos que vaig fent per a mi.
No estan degudament documentats i son tan en Català com en Castellà.

  1. PS2
  2. Diisplay 7 Segments
  3. Shield LCD amb teclat
  4. Pedals
  5. Control d’acces
  6. Matriu max7219
  7. Pont H L293H
  8. Termòstat Incubadora

PS2

Display 7 Segments

En esta ocasión os quiero compartir el esquema de conexión de un display de 4 dígitos y 7 segmentos. Dicha conexión la realizamos con un registro de desplazamiento, el 74HC595, dicho módulo nos evite tener que conectar los 12 pines al Arduino y con solo tres de pines a la placa controlamos los 7 segmentos.

Por otro lado, conectamos directamente los cables de cada uno de los dígitos a la placa mediante una resistencia de 330ohm.

Al trabajar con dicho componente no podemos usar la instrucción usar la instrucción “delay()” ya que no nos funcionaria correctamente, con lo cual debemos hacer comprobaciones con la instrucción “millis()” o hacer otro método para provocar un retardo.

Dicha librería nos permite varias cosas que hacer con el display, como, por ejemplo: usar el mismo código para un módulo de Ánodo o Cátodo, controlar la intensidad de los leds, indicándole que punto es el decimal, etc.

Esquema de conexión:

Aplicación:

/*
 * Autor: Josep Martinez Tejedor
 * Fecha: 21 de febrero de 2022
 * Web: josepmt.com
 */
#include <SevSegShift.h>

#define SHIFT_PIN_SHCP 6
#define SHIFT_PIN_STCP 5
#define SHIFT_PIN_DS   4

SevSegShift sevseg(SHIFT_PIN_DS, SHIFT_PIN_SHCP, SHIFT_PIN_STCP, 1, true);

void setup() {
  byte numDigits = 4;
  byte digitPins[] = {9, 10, 11, 12}; // Aquests són els PIN de la ** Arduino **
  byte segmentPins[] = {0, 1, 2, 3, 4, 5, 6, 7}; // Aquests són els PIN de la ** del registo e desplazamiento **
  bool resistorsOnSegments = false;     //'falso' significa que las resistencias están en pines de dígitos
  byte hardwareConfig = COMMON_ANODE;   // Ver README.md para opciones
  bool updateWithDelays = false;        // Por defecto 'falso' es Recomendado
  bool leadingZeros = false;            // Use 'true' si desea mantener los ceros iniciales
  bool disableDecPoint = false;         // Use 'true' si su punto decimal no existe o no está conectado. Luego, solo necesita especificar 7 segmentPins[]

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(20);           // Intensiad de los leds hasta 90
}

void loop() {
  static unsigned long tiempoejec=millis()+100; //proximo evento
  static int contador=0;

  if(millis()>=tiempoejec){
    tiempoejec+=100;      //proximo evento
    contador++;
    if(contador==10000){
      contador=0;         //reseteamos contador
    }
    sevseg.setNumber(contador,1);  // El segundo parámetro indica la posición del punto decimal.
  }
  sevseg.refreshDisplay();
}
/*
 * Autor: Josep Martinez Tejedor
 * Fecha: 21 de febrero de 2022
 * Web: josepmt.com
 */
#include <SevSegShift.h>

#define SHIFT_PIN_SHCP 6
#define SHIFT_PIN_STCP 5
#define SHIFT_PIN_DS   4

SevSegShift sevseg(SHIFT_PIN_DS, SHIFT_PIN_SHCP, SHIFT_PIN_STCP, 1, true);

void setup() {
  byte numDigits = 4;
  byte digitPins[] = {9, 10, 11, 12}; // Aquests són els PIN de la ** Arduino **
  byte segmentPins[] = {0, 1, 2, 3, 4, 5, 6, 7}; // Aquests són els PIN de la ** del registo e desplazamiento **
  bool resistorsOnSegments = false;     //'falso' significa que las resistencias están en pines de dígitos
  byte hardwareConfig = COMMON_CATHODE; // Ver README.md para opciones COMMON_CATHODE   COMMON_ANODE
  bool updateWithDelays = false;        // Por defecto 'falso' es Recomendado
  bool leadingZeros = false;            // Use 'true' si desea mantener los ceros iniciales
  bool disableDecPoint = false;         // Use 'true' si su punto decimal no existe o no está conectado. Luego, solo necesita especificar 7 segmentPins[]

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(20);           // Intensiad de los leds hasta 90
}

void loop() {
  static unsigned long tiempoejec=millis()+100; //proximo evento
  static int contador=0;

  if(millis()>=tiempoejec){
    tiempoejec+=100;      //proximo evento
    contador++;
    if(contador==10000){
      contador=0;         //reseteamos contador
    }
    sevseg.setNumber(contador,1);   // El segundo parámetro indica la posición del punto decimal.
  }
  sevseg.refreshDisplay();
}

Descarga de la libreria:

SevSegShift-ShiftRegister: Descargas

Shield LCD amb teclat

En esta ocasión os quiero compartir el esquema de conexión de un display de 4 dígitos y 7 segmentos. Dicha conexión la realizamos con un registro de desplazamiento, el 74HC595, dicho módulo nos evite tener que conectar los 12 pines al Arduino y con solo tres de pines a la placa controlamos los 7 segmentos.

Por otro lado, conectamos directamente los cables de cada uno de los dígitos a la placa mediante una resistencia de 330ohm.

Al trabajar con dicho componente no podemos usar la instrucción usar la instrucción “delay()” ya que no nos funcionaria correctamente, con lo cual debemos hacer comprobaciones con la instrucción “millis()” o hacer otro método para provocar un retardo.

Dicha librería nos permite varias cosas que hacer con el display, como, por ejemplo: usar el mismo código para un módulo de da Ánodo o Cátodo, controlar la intensidad de los les, indicarle que punto es el decimal, etc.

Este componente va directamente encima de la placa:

Aplicación:

/*
 * Autor: Josep Martinez Tejedor
 * Fecha: 23 de febrero de 2022
 */

// incluir el código de la biblioteca:
#include <LiquidCrystal.h>
int contador = 0;

// inicialice la biblioteca con los números de los pines de la interfaz
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Definición de caracteres especiales
byte vocal1[8] = {B00010, B00100, B00000, B01110, B00001, B01111, B10001, B01111}; // letra á
byte vocal11[8] = {B00100, B00010, B00000, B01110, B00001, B01111, B10001, B01111}; // letra à

byte vocal2[8] = {B00010, B00100, B00000, B01110, B10001, B11111, B10000, B01110}; // letra é
byte vocal21[8] = {B01000, B00100, B00000, B01110, B10001, B11111, B10000, B01110}; // letra è

byte vocal3[8] = {B00010, B00100, B00000, B01100, B00100, B00100, B00100, B01110}; // letra í

byte vocal4[8] = {B00010, B00100, B00000, B01110, B10001, B10001, B10001, B01110}; // letra ó
byte vocal41[8] = {B01000, B00100, B00000, B01110, B10001, B10001, B10001, B01110}; // letra ò

byte vocal5[8] = {B00010, B00100, B00000, B10001, B10001, B10001, B10011, B01101}; // letra ú

byte ela[8] = {B00000, B11000, B01000, B01000, B01010, B01000, B01000, B11100}; // letra l·

byte enya[8] = {B00000, B01110, B00000, B10110, B11001, B10001, B10001, B10001}; // letra ñ

byte c[8] = {B00000, B00000, B01110, B10000, B10000, B10010, B01111, B00100}; // letra ç

// FUNCIO DEL TECLAT A0
byte key(){
  // 1 = 639; 2 = 409, 3 = 99, 4 = 256, 5 = 0
  int val = analogRead(0);
  if (val < 50) return 5;
  else if (val < 125) return 3;
  else if (val < 300) return 4;
  else if (val < 450) return 2;
  else if (val < 700) return 1;
  else if (val < 1023) return 0;
}

void setup() {
  lcd.createChar(1, vocal1);
  lcd.createChar(2, vocal11);
  lcd.createChar(3, vocal2);
  lcd.createChar(4, vocal21);
  lcd.createChar(5, vocal3);
  lcd.createChar(6, vocal4);
  lcd.createChar(7, vocal41);
  lcd.createChar(8, vocal5);
  lcd.createChar(9, ela);
  lcd.createChar(10, enya);
  lcd.createChar(11, c);

  // configurar el número de columnas y filas de la pantalla LCD:
  lcd.begin(16, 2);
  lcd.clear();
  analogWrite(10, 30);


}

void loop() {
  // Posicionamos el cursor en la columna 0, linea 1
  // (nota: La linea 1 corresponde a la segunda fila, ya que el conteo comienza con 0):
  lcd.setCursor(0, 1);
  // imprimir el número de segundos desde el reinicio:
  lcd.print(millis() / 1000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("analogRead ");
  lcd.print(analogRead(0));
  lcd.setCursor(0, 1);
    switch (key()){
      case 1:
        lcd.print("Selecci");
        lcd.write(byte(6));   // Muestra la o acentuada
        lcd.print("n:  ");
        break;
      case 2:
        lcd.print("Izquierda:  ");
        break;
      case 3:
        lcd.print("Arriba:");
        // Muestra un contador en la segunda fila y posición 13
        contador = contador + 1;
        lcd.setCursor(13, 1);
        lcd.print(contador);
        break;
      case 4:
        lcd.print("Aba.");
        // Escribe los caracteres acentuados
        lcd.setCursor(5,1);
        lcd.write(byte(1));
        lcd.write(byte(2));
        lcd.write(byte(3));
        lcd.write(byte(4));
        lcd.write(byte(5));
        lcd.write(byte(6));
        lcd.write(byte(7));
        lcd.write(byte(8));
        lcd.write(byte(9));
        lcd.write(byte(10));
        lcd.write(byte(11));
        break;
      case 5:
        lcd.print("Derecha:");
        break;
    }
  delay(250);
}

Pedals

Contol d’Acces

/*
Programa: Control de Acceso a Puertas con RC522
Autor:  Humberto Higinio
Facebook: https://www.facebook.com/humberto.higinio
Instagram: https://www.instagram.com/humberto.higinio/
Twitter: https://twitter.com/hhiginio
Canal de Youtube: https://www.youtube.com/user/HHSolis
Video Exclusivo para mi canal de Youtube
Todos los Derechos Reservados - 2019
Código de Dominio Público

 *
 * Typical pin layout used:
 * -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 */


#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9
#define RELAY 6 // Pin del Relay
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Crea la instancia MFRC522

//byte Usuario1[4]= {0xE6, 0xCD, 0xE7, 0xA0} ;    // NUMERO DEL USUARIO 1 (ponga el de su tarjeta)
//byte Usuario1[4]= {0xE6, 0xCD, 0xE7, 0xA0} ;    // NUMERO DEL USUARIO 2 (ponga el de su tarjeta)
int vermell = 2;
int verd = 3;

void setup()
{
  Serial.begin(9600);   // Inicializa la comunicacion serial
  SPI.begin();          // Inicializa el bus SPI
  mfrc522.PCD_Init();   // Inicializa el MFRC522
  pinMode(RELAY, OUTPUT);
  digitalWrite(RELAY, LOW);
  Serial.println("Ponga su Tarjeta para la lectura...");
  Serial.println();

  pinMode(vermell, OUTPUT);
  pinMode(verd, OUTPUT);
  digitalWrite(vermell, HIGH);
}
void loop()
{
  // Mirando para nuevas tarjeras
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  // Selecciona una de las tarjetas
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
  // Muestra el UID sobre el Monitor Serial
  Serial.print("UID tag :");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Message : ");
  content.toUpperCase();
  if (content.substring(1) == "E0 8E 8F 7C") //Cambie aqui el UID de las tarjetas que usted desea dar acceso
  {
    Serial.println("Acceso Autorizado targeta");
    digitalWrite(vermell, LOW);
    digitalWrite(verd, HIGH);
    digitalWrite(RELAY, HIGH);
    delay(1000);
    digitalWrite(RELAY,LOW);
    digitalWrite(vermell, HIGH);
    digitalWrite(verd, LOW);
  }

  if (content.substring(1) == "B0 2C 22 83") //Cambie aqui el UID de las tarjetas que usted desea dar acceso
  {
    Serial.println("Acceso Autorizado clauer");
    digitalWrite(RELAY, HIGH);
    digitalWrite(vermell, LOW);
    digitalWrite(verd, HIGH);
    delay(1000);
    digitalWrite(RELAY,LOW);
    digitalWrite(vermell, HIGH);
    digitalWrite(verd, LOW);
  }

}

Matriu max7219

#include <MatrizLed.h>
MatrizLed pantalla;


void setup() {
  // put your setup code here, to run once:
pantalla.begin(12,11,10,1);   // (Dpin,Clk,cs,#matrices)
pantalla.setIntensidad(10);    // de 1 a 15 donde 15 es la mayor intensidad
pantalla.borrar();
delay(2000);
pantalla.setLed(0,0,0,true); // (#matriz, fila, columna, estado);
pantalla.setLed(0,1,1,true);
pantalla.setLed(0,2,2,true);
pantalla.setLed(0,3,3,true);
pantalla.setLed(0,4,4,true);
pantalla.setLed(0,5,5,true);
pantalla.setLed(0,6,6,true);
pantalla.setLed(0,7,7,true);
delay(2000);
efectoHorizontal();
efectoVertical();
efectoHorizontal();
efectoVertical();
efectoHorizontal();
efectoVertical();
pantalla.escribirCaracter('E',0); //(Caracter, Pantalla)
delay(500);
pantalla.escribirCaracter('L',0);
delay(500);
pantalla.escribirCaracter('E',0);
delay(500);
pantalla.escribirCaracter('C',0);
delay(500);
pantalla.escribirCaracter('T',0);
delay(500);
pantalla.escribirCaracter('R',0);
delay(500);
pantalla.escribirCaracter('O',0);
delay(500);
pantalla.escribirCaracter('N',0);
delay(500);
pantalla.escribirCaracter('I',0);
delay(500);
pantalla.escribirCaracter('C',0);
delay(500);
pantalla.escribirCaracter('S',0);
delay(500);
pantalla.escribirCaracter('P',0);
delay(500);
pantalla.escribirCaracter('O',0);
delay(500);
pantalla.escribirCaracter('T',0);
delay(500);
}

void loop() {
  // put your main code here, to run repeatedly:
// vamos a escribir el nombre que queramos, en mi caso ElectronicSpot,
// en modo scroll hacia la izquierda

pantalla.escribirFraseScroll("ELECTRONIC SPOT",100);

}

void efectoHorizontal(){
  for (int i = 0;i <= 7; i++){
    for (int j = 0;j <= 7; j++){
      pantalla.setLed(0,i,j,true);    //enciende 8 leds de cada fila
    }
    delay(50);
    for (int j = 0;j <= 7; j++){
      pantalla.setLed(0,i,j,false);   //apaga 8 leds de cada fila
    }
  }
  for (int i = 6; i >=0; i--){
    for (int j = 0;j <= 7; j++){
      pantalla.setLed(0,i,j,true);    //enciende 8 leds de cada fila
    }
    delay(50);
    for (int j = 0;j <= 7; j++){
      pantalla.setLed(0,i,j,false);   //apaga 8 leds de cada fila
    }
  }
}

void efectoVertical(){
   for (int i = 0;i <= 7; i++){
    for (int j = 0;j <= 7; j++){
      pantalla.setLed(0,j,i,true);    //enciende 8 leds de cada fila
    }
    delay(50);
    for (int j = 0;j <= 7; j++){
      pantalla.setLed(0,j,i,false);   //apaga 8 leds de cada fila
    }
  }
  for (int i = 6; i >=0; i--){
    for (int j = 0;j <= 7; j++){
      pantalla.setLed(0,j,i,true);    //enciende 8 leds de cada fila
    }
    delay(50);
    for (int j = 0;j <= 7; j++){
      pantalla.setLed(0,j,i,false);   //apaga 8 leds de cada fila
    }
  }
}

Pont H L293D

int mda=7;
int mdr=8;
int vel=5;

void setup() {
  Serial.begin(9600);
  pinMode(mda, OUTPUT);
  pinMode(mdr, OUTPUT);
  pinMode(vel, OUTPUT);

  digitalWrite(mda, LOW);
  digitalWrite(mdr, LOW);
  analogWrite(vel, 0);
}

void loop() {
  // Gir sentit horari
  digitalWrite(mda, HIGH);
  digitalWrite(mdr, LOW);
  velocitat_augmenta();
  velocitat_decrementa();
  delay(1000);

  // Para motors
  digitalWrite(mda, LOW);
  digitalWrite(mdr, LOW);
  delay(1000);

  // Gir sentit antihorari
  digitalWrite(mda, LOW);
  digitalWrite(mdr, HIGH);
  velocitat_augmenta();
  velocitat_decrementa();
  delay(1000);
}

void velocitat_augmenta(){
  int i,j;
  for(i=127; i<=255; i++){
    analogWrite(vel, i);
    Serial.print("Valor de i: ");
    Serial.println(i);
    delay(20);
  }
  Serial.println("Canvi...");
}

void velocitat_decrementa(){
  int i;
  for(i=255; i>=127; i--){
    analogWrite(vel, i);
    Serial.print("Valor de i: ");
    Serial.println(i);
    delay(20);
  }
  Serial.println("Fi del cicle");
}

Termòstat Incubadora

/* 
 *  ATMega 328P (Old BootLoader) Arduino Nano
 *  Rele 11 Gris
 *  Led 13 Vermell
 *  Senso moviment 12 Carbaça, vermell Vcc
 *  Sensor de llum A6 verd i a ppositiu amb una resistencia
 *  Display Din 2 Carbaça
 *          Clk 3 Marro ==> vermell
 *  Pulsador blau    4        
 *  Pulsador vermell 5
 *  Termemotre       6
 *  
 * Termometre:
 * https://programarfacil.com/blog/arduino-blog/ds18b20-sensor-temperatura-arduino/
 * Display 4 de 7 Segments:
*/  
#include <OneWire.h>
#include <DallasTemperature.h>
#include "TM1637.h"

#define CLK 7 // Pin CLK
#define DIO 6 // Pin DIO
TM1637 tm1637(CLK,DIO);

int rele = 11;
int led = 13;
const int bblau = 4;
const int bvermell = 5;
int tmax = 37;
int tmin = 0;
int tactual;
int periodo = 4000;
unsigned long TiempoAhora = 0;
int vdisplay = 0;
 

// Pin donde se conecta el bus 1-Wire del termometro
const int pinDatosDQ = 2;

// Instancia a las clases OneWire y DallasTemperature
OneWire oneWireObjeto(pinDatosDQ);
DallasTemperature sensorDS18B20(&oneWireObjeto);
 
void setup() {
    // Iniciamos la comunicación serie
    Serial.begin(9600);
    // Iniciamos el bus 1-Wire
    sensorDS18B20.begin(); 
    
    // Display d4 de 7 segmentos
    tm1637.init(); // Inicializa modulo
    tm1637.set(2); // Brillo, 0 (minimo) a 7 (maximo)
    tm1637.point(POINT_ON); // Apaga dos puntos, POINT_ON para encenderlos

    pinMode(rele, OUTPUT);
    pinMode(led, OUTPUT);

    //Configuramos el pin del botón como entrada de pull-up
    pinMode(bblau, INPUT_PULLUP);
    pinMode(bvermell, INPUT_PULLUP);
}
 
void loop() {
    // Mandamos comandos para toma de temperatura a los sensores
    // Serial.println("Mandando comandos a los sensores");
    sensorDS18B20.requestTemperatures();
 
    // Leemos y mostramos los datos de los sensores DS18B20
    Serial.print("Temperatura sensor 0: ");
    Serial.print(sensorDS18B20.getTempCByIndex(0));
    Serial.println(" C");

    // Convercio de la temperatura
    int vtemp= sensorDS18B20.getTempCByIndex(0)*100.0; // centGrados=2756
    tactual = sensorDS18B20.getTempCByIndex(0); // Sense decimals

    //Guardamos en una variable la lectura del botón
    //En pull-up guardará 1 no pulsado, 0 pulsado
    int botob = digitalRead(bblau);
    int botov = digitalRead(bvermell);

    if (botob == 0){
      tmax = tmax - 1;
      Serial.print("...............  ");
      Serial.println(tmax);
      vdisplay = 1;
      TiempoAhora = millis();
    }  
    
    if (botov == 0){
      tmax = tmax + 1;
      Serial.print("...............  ");
      Serial.println(tmax);
      vdisplay = 1;
      TiempoAhora = millis();
    }  

    // Control del rele

    // Si la temperatura está per sota a ...
    if(tactual < tmax){
      if (tmin > 0){
        if (tactual < tmax -1){ 
          tmin = 0;
        }
      }else{
      digitalWrite(rele, HIGH);
      digitalWrite(led, HIGH);
    }
    }

    // Si la temperatura es iggual a tmax apegar la calor
    if(tactual >= tmax){
      digitalWrite(rele, LOW);
      digitalWrite(led, LOW);
      tmin = 1;
    }

    //Serial.println(vtemp);
    
    if(millis() > TiempoAhora + periodo){
        TiempoAhora = millis();
        vdisplay = 0;
    }

    
    if (vdisplay == 0){ 
        tm1637.display(0, (vtemp/1000)%10); // Digito 0 => 9
        tm1637.display(1, (vtemp/100)%10); // Digito 1 => 8  vTemperatura.charAt(1)
        tm1637.display(2, (vtemp/10)%10); // Digito 2 => 7
        tm1637.display(3, 43); // Digito 3 => 6    vtemp%10, 0x0c
    }else{
        tm1637.display(0, (tmax/10)%10); // Digito 0 => 9
        tm1637.display(1, (tmax/1)%10); // Digito 1 => 8  vTemperatura.charAt(1)
        tm1637.display(2, 0x0c); // Digito 2 => 7
        tm1637.display(3, 43); // Digito 3 => 6    vtemp%10, 0x0c
    }
}

Scroll al inicio