Y este es el codigo completo del Arduino, aunque esta a medio modificar, para usar dos oled, ya que antes usaba dos arduinos, uno por oled, ya que a las pantallas no se les puede cambiar la direccion.
Ahora estoy modificandolo para usar un multiplexor I2c.
Por eso estta a medias sin parciales y GPS en ese codigo
VEras que esta supercomentado porque comparto el codigo con quien lo quiera, asi que asi se entiende mejor
type or paste code here
/*VELOCIMETRO
VELOCIDAD Frecuencia
20 2,86
40 5,71
60 8,57
80 11,43
100 14,28
120 17,14
140 19,99
160 22,85
180 25,71
----------------
Conexiones
Sensor hall 2
GPS 3 y 4
Motor 5,6.7 y 8
Pulsador 11
I2c SDA A4 SCL A5
*/
#include <Adafruit_SPIDevice.h>
#include <Adafruit_I2CRegister.h>
#include <Adafruit_I2CDevice.h>
#include <Adafruit_BusIO_Register.h>
#include "SwitecX25.h" // Libreria para el control del motor paso a paso
#include <SPI.h> // Libreria para el uso del i2c de comunicacion del LCD
#include <Wire.h> // Libreria para el uso del i2c de comunicacion con el LCD
#include <Adafruit_GFX.h> // Libreria para el uso del LCD OLED
#include <Adafruit_SSD1306.h> // Libreria para el uso del LCD OLED
#include "TinyGPS++.h" // Libreria para el uso del modulo GPS
#include <EEPROM.h> // Libreria para el uso de la memoria fija
//************ DATOS A VARIAR EN FUNCION DE CADA MOTO Y KM RECORRIDOS ************
// Datos para una rueda 90/90/18
const float desarollo_rueda = 1.945; //En mm, hace falta para calcular la velocidad
// ***** DEFINICIONES (valores fijos) *******
#define hallPin 2 // Pin donde esta conectado el sensor hall
#define STEPS (315*3) // recorrido total en pasos del motor 945 pasos
#define RECORRIDO_ESCALA 780 // pasos del recorrido desde el tope cero al tope max velocidad
#define SCREEN_WIDTH 128 // OLED display ancho, en pixels
#define SCREEN_HEIGHT 32 // OLED display alto, en pixels
// Declaracion para un display SSD1306 conectado a I2C (SDA, SCL pins)
// Los pins para I2C estan definidos en la libreria Wire-library.
// En un arduino NANO: A4(SDA), A5(SCL)
// es donde conectamos la tarjeta de multiplexor I2C Pines A4 y A5
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C // <Direccion de la pantalla OLED; 0x3D para 128x64, 0x3C para 128x32
//*********************************************************************************
// *** VARIABLES QUE USA EL PROGRAMA *******
volatile float tiempo0 = 0;
volatile float tiempo1 = 0;
float rpm_rueda;
float rps_rueda;
float velocidad;
float metros;
long km;
int posicion_aguja;
long num;
//*****************************************
// CREA INSTANCIAS A LA PANTALLA OLED, AL MOTOR Y AL BOTON, PARA SU USO
Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Motor conectado a los pins 56,7,8
SwitecX25 motor1(STEPS,5,6,7,8);
//**********************************************
//*********** SETUP DE INICIO DEL ARDUINO, SE EJECUTA UNA VEZ AL CONECTARLE ALIMENTACION ****
void setup()
{
//Inicializacion del sistema
pinMode(8, OUTPUT);
pinMode(hallPin, INPUT_PULLUP);
// PREPARAR COMUNICACION SERIAL
Serial.begin(9600);
// Prepara el display
// Start Wire library for I2C
Wire.begin();
// initialize OLED-1 with I2C addr 0x3C
TCA9548A(1);
if(!display1.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
{
for(;;); // No responde, espera en bucle infonito
}
display1.setTextColor(SSD1306_WHITE); // Texto en blanco
display1.setTextSize(4); // Escala del texto 4X
TCA9548A(2);
if (!display2.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
{
for (;;); // No responde, espera en bucle infonito
}
display2.setTextColor(SSD1306_WHITE); // Texto en blanco
display2.setTextSize(4); // Escala del texto 4X
// lee los km del total de la memoria del velocimetro. Si lee cero graba la que esta predefinida en el #define KM_HOY
EEPROM.get(2, km);
if ((km == -1)||(km==0)) // Si es la primera vez que se usa, no hay km recorridos memorizados, asi que memoriza
{ // lo que se haya fijado en la cabecera del programa como inicial
EEPROM.put(2, km);
}
dato_al_display(km,0,1); // manda al display los km recorridos memorizados en la eeprom
// PREPARA EL INSTRUMENTO DE AGUJA HACIENDO UN BARRIDO
prepara_gauge(); // hace un barrido del recorrido del motor paso a paso y lo pone a 0km/h
//Declaramos la interrupcion. En el arduino NANO. En el pin 2 se encuentra la interrupcion 0
//Como tenemos una resistencia de PULL-UP nos interesa ejecutar el codigo cuando pasa de 5V a 0V --> FALLING
attachInterrupt(0, pulsoRueda, FALLING);
}
//****************************************************************
// PROGRAMA QUE SE EJECUTA DE FORMA CICLICA REPETITIVA ***********
void loop()
{
// si la moto esta parada, no llegan pulsos de la rueda y el tiempo entre pulsos es largo
if ((micros() - tiempo1) > 1000000)
{
// considera que la velocidad es cero, por debajo de un valor
rpm_rueda = 0;
}
// calcula la posicion de la aguja en funcion de la velocidad medida
// (el recorrido real de la aguja desde el bloqueo a 10km/h es 180-10 => 780 pasos)
// por tanto se ajusta la escala de rpm_rueda a esos 780 pasos de recorrido de la aguja
delay(2); // para quitar la vibracion de la aguja actualiza la posicion paso a paso cada 8 mseg
if (posicion_aguja < int(rpm_rueda * 0.21477))
posicion_aguja++;
if (posicion_aguja > int(rpm_rueda * 0.21477))
posicion_aguja--;
motor1.setPosition(posicion_aguja); // pone la aguja en la posicion de velocidad actual
motor1.updateBlocking();
if(metros > 1000) // se se han recorrido 1000 metros suma un km al total
{
metros = 0;
km++;
if(km > 99999)
km=0;
dato_al_display(km,0,1);
EEPROM.put(2,km ); // graba en la memoria los km recorridos
}
}
//***********************************************************
//****************** FUNCIONES ******************************
// hace el barrido de todo el recorrido de la aguja para preparar el velocimetro
void prepara_gauge(void)
{
motor1.maxVel=30;
motor1.setPosition(0);
motor1.updateBlocking();
motor1.setPosition(STEPS); // lleva el motor a la pos 180km/h
motor1.updateBlocking();
delay(400);
motor1.setPosition(0); // lleva el motor a la pos 180km/h
motor1.updateBlocking();
motor1.maxVel=80;
motor1.update();
}
// visualiza en el display un nuevo valor
void dato_al_display(float dato, int decimales, int pantalla)
{
TCA9548A(pantalla);
display1.clearDisplay();
if ((dato > 9999))
display1.setCursor(5,2); // Comienza en la esquina superior izda
if ((dato > 999) && (dato < 10000))
display1.setCursor(30,2); // Comienza en la esquina superior izda
if ((dato > 99) && (dato < 1000))
display1.setCursor(42, 2); // Comienza en la esquina superior izda
if ((dato < 100)&&(dato > 9))
display1.setCursor(55, 2); // Comienza en la esquina superior izda
if (dato < 10)
display1.setCursor(65, 2); // Comienza en la esquina superior izda
display1.println(dato,decimales);
display1.display();
}
// funcion que se ejecuta cada vez que hay un pulso enl detector de la rueda
void pulsoRueda()
{
tiempo1 = micros();
rps_rueda = (1000000 / (tiempo1 - tiempo0));
tiempo0 = tiempo1;
rpm_rueda = rps_rueda * 60; // pasa de rps a rpm
velocidad = (rps_rueda * desarollo_rueda * 3.6); // pasa de rps a m/h
metros = metros + desarollo_rueda;
}
// funcion para el multiplexor i2c
void TCA9548A(uint8_t bus)
{
Wire.beginTransmission(0x70); // TCA9548A address is 0x70
Wire.write(1 << bus); // send byte to select bus
Wire.endTransmission();
}