Mostrando entradas con la etiqueta Arduino. Mostrar todas las entradas
Mostrando entradas con la etiqueta Arduino. Mostrar todas las entradas

miércoles, 23 de noviembre de 2016

Termostato de calefacción con Arduino Mega y 2.4'' TFT

Termostato básico para calefacción con arduino mega, tft 2.4'' y 3 sondas de temperatura por cable.
(Para la calibración de la temperatura he utilizado código de calibracion temperatura según Sketch de David Losada, basado en trabajos de Rafael Torrales y Antonio Moles.)  Supondo que sería más facil usar componentes dedicados, pero  teníalas sondas por casa y cuando me dí cuenta ya las estaba utilizando.  :)

Para el funcionamiento de la tft me he basado en el texto y codigo de esta página y las librerías Adafruit_TFTLCD, Adafruit_GFX y TouchScreen.
 En mi pantalla ftf los ejemplos aportados por estas librerías dieron algún problema de orientación, que pude solucionar facilmente cambiando el valor de tft.rotation()

El accionamiento es mediante optoacoplador, que deberá ser adecuado a la tensión e intensidad que vienen de la caldera. En mi caso han sido 18V y 7mA. Es necesario respetar la polaridad en las entradas del optoacoplador. 

Muestra una gráfica  con las temperaturas de las últimas 26 horas, dispone de  una alarma que suena si la temperatura del sensor nº2 baja de 1ºC (para la habitación donde está la caldera )

En esta página muestro la versión con temporizador.

Descargar  sketch











Aspecto general.






                                           Sondas de temperatura.






Menú ptrincipal.







                         Fijando la temperatura de disparo.





 Gráfica de temperaturas








Código:



/*  ===============================================================
Termostato Arduino Mega y tft 2.4''
    ==================================================================   */

//#include

// *** SPFD5408 change -- Begin
#include     // Core graphics library
#include // Hardware-specific library
#include
// *** SPFD5408 change -- End


#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

//Puertas de lectura del TFT
#define YP A1
#define XM A2
#define YM 7
#define XP 6
 
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940

 

#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// optional
#define LCD_RESET A4

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 
//Colores
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
 
  Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
 
//Calibracion temperatura según Sketch de David Losada, basado en trabajos de Rafael Torrales y Antonio Moles.

//Para ahorrar cálculos, lo vamos a calcular antes del programa
const float TPto1 = -12; //Temperatura en ºC punto 1
const float RPto1 = 69200; // Ohms en punto 1
const float TPto2 = 33.5; // Temp. punto 2
const float RPto2 = 7270; // Ohms en punto 2
const float resistor = 8120; //El valor en ohmnios de la resistencia del termistor a 25ºC
const float voltage = 4.93; // El voltaje real en el punto 5Vcc de tu placa Arduino
//Para ahorrar cálculos lo definimos como constante en esta parte del programa
const float K = 273.15; //Para pasar a grados Kelvin
const float e = 2.718281828459045; //Constante matemática
const float B = log(RPto2 / RPto1) / (1 / (TPto2 + K) - (1 / (TPto1 + K))); //Valor Beta de tu termistor
const float unodivr = 1 / (resistor * pow(e, (-B / 298.15))); //Con pow elevamos e al resultado

unsigned long inicio;// control del tiempo



   bool optoac=0;
  String texto="Encender";

float T[3] = {0}; //Declaramos la variable Temperatura
float tmedia[3] = {0}; //Variable para calcular media
int cnt; //temperatura media y contador

short tp1[320]; // almacen de temperaturas1 para grafico
short tp2[320]; // almacen de temperaturas2 para grafico
short tp3[320]; // almacen de temperaturas3 para grafico
int tp; // puntero almacet Tª
int tpp;

float termostato=21.0; // Temperatura del termostato a 21ºC

char enl;

void setup()   {
  // Iniciamos comunicacion serie con pantalla     
  Serial.begin(9600);

pinMode(45, OUTPUT); // Preparar salida audio pin 45
pinMode(38, OUTPUT); // Salida  optoacoplador
  //
  tft.reset();
  uint16_t identifier = tft.readID();
  Serial.print(F("LCD driver chip: "));
  Serial.println(identifier, HEX);
  tft.begin(identifier);
  tft.fillScreen(BLACK);
  pinMode(13, OUTPUT);
  
  inicio = millis();
 
}

#define MINPRESSURE 100
#define MAXPRESSURE 1000

void loop()
{

  // Selecciona la entrada para el termistor
 
  int sensorValue[3]; // Aqui almacenamos el valor de las sondas
  byte sonda; // sondas
   
  // Parte 1:  Leemos el puerto analógico 0 y convertimos el valor en voltios.
  sensorValue[0] = analogRead(A13); //Leemos analógico 0
  sensorValue[1] = analogRead(A14); //Leemos analógico 1
  sensorValue[2] = analogRead(A15); //Leemos analógico 2

  // medimos la temperatura 10 veces y la almacenamos en tmedia
  for ( cnt = 0; cnt < 10; cnt++)
  {
    sensorValue[0] = analogRead(A13); //Leemos analógico 0
    sensorValue[1] = analogRead(A14); //Leemos analógico 1
    sensorValue[2] = analogRead(A15); //Leemos analógico 2

    tmedia[0] = tmedia[0] + sensorValue[0];
    tmedia[1] = tmedia[1] + sensorValue[1];
    tmedia[2] = tmedia[2] + sensorValue[2];

  }

  for (sonda = 0; sonda < 3; sonda = sonda + 1) { // Bucle para las tres sondas

    // calculamos la media de las medidas
    tmedia[sonda] = tmedia[sonda] / 10;

    //Convertimos a voltios :)
    float v2 = (voltage * float(tmedia[sonda])) / 1024.0f;

    tmedia[sonda] = 0; // limpiamos la variable

    // Parte 2: Calcular la resistencia con el valor de los voltios mediante la ecuación del divisor de voltaje
    //voltage = 4.83
    //R2 = 10000
    //R1 = Thermistor resistance
    //V2= v2
    //so V2=(R2*V)/(R1+R2)
    //and r1=((r2*v)/v2)-r2 <--final br="">
    float r1a = (voltage * float(resistor)) / v2;
    float r1 = r1a - resistor;


    //Parte 3: Calcular la temperatura basandose en la ecuación Steinhart-Hart y la ecuación del valor Beta.
    // T=B/ln(r1/rinfinit)


    T[sonda] = int((10*((B / log(r1 * unodivr)) - 273.15))); T[sonda]=T[sonda]/10; //Convertimos a ºC y ya tenemos la temperatura


  } // Fin for sondas

  if ( millis() - inicio > 300000 ) { // ciclo muestreo datos cada 5 minutos (300000)
    inicio = millis();

      tp=tp+1;
      if (tp>=320){ tp=0;}

    for (sonda = 0; sonda < 3; sonda = sonda + 1) {
     
      // Almacenaje temperaturas
      if (sonda==0){
        tp1[tp]=T[sonda]*100;
      }
     
      if (sonda==1){
        tp2[tp]=T[sonda]*100;
      }
     
      if (sonda==2){
        tp3[tp]=T[sonda]*100;
      }
        }     
  } // Fin del if

        temp(); //Mostrar temperaturas en el tft

if (optoac==1){    // Encendido apagado calefacc´on. Comprobar termostato
  if (T[0]<=(termostato-0.5)){  // Activar   
  digitalWrite(38, HIGH);
  }
 
    if (T[0]>(termostato+0.2)){// Desactivar     
  digitalWrite(38, LOW);
   }
  }  // fin  if pulsacionn 


if (T[1]<1 -galer="" 1000="" 1500="" a="" alarma="" br="" de="" en="" helada="" nbsp="" t="" tone="">       
}  // FIN LOOP


  ////////        MOSTRAR MENU PRINCIPAL
void MenuP()
{
byte esquinax;
int ciclo;

//  digitalWrite(13, HIGH);
//  digitalWrite(13, LOW);
    pinMode(XM, OUTPUT); //Pins configures again for TFT control
    pinMode(YP, OUTPUT);
TSPoint p;

  //Texto botoes
  tft.fillScreen(BLACK);
   tft.setRotation(1);
  tft.setTextSize(3);
  tft.setCursor(90, 20);
  tft.setTextColor(YELLOW);
  tft.println("Temperatura");
  tft.setCursor(90, 80);
  tft.setTextColor(GREEN);
  tft.println("Grafica");
  tft.setCursor(90, 140);
  tft.setTextColor(CYAN);
  tft.println(texto);
  tft.setTextColor(WHITE);
  tft.setCursor(90, 200);
  tft.print("Termostato");
    tft.setRotation(0);

//  triangulos
  for (esquinax=25; esquinax<200 esquinax="esquinax+60){<br"> tft.fillTriangle(esquinax+7, 5, esquinax, 75, esquinax-7, 5, (RED));
}
 tft.fillTriangle(200, 5, 213, 5,206 ,75, (RED));

 //Menu principal

  for (ciclo=0; ciclo<10000 br="" ciclo="">      p = ts.getPoint();
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
  {
    p.x = tft.width()-(map(p.x, TS_MINX, TS_MAXX, tft.width(), 0));
    p.y = tft.height()-(map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));

   tone (45, 400, 180);
    // PULSACIÓN
   
       if (p.y <70 br="" temperatura="" testar="">       {
        temp();
              }
             
       else if (p.y <140 amp="" p.y=""> 70)         //Testar grafica
       {        
         lecturaD();
                }
               
       else if (p.y < 210 & p.y >140)            // On/off 
       {
         enc();       
       }
      
       else if (p.y >210)        //Fija la temperatura del termostato
       {
       termost();
       ciclo=10000;
         }
  }
}// fin for ciclo
}


//                Mostrar temperatura en tft
void temp() {
  char temp[2]; 
  byte num;
 
    pinMode(XM, OUTPUT); //Pins configures again for TFT control
    pinMode(YP, OUTPUT);

     tft.fillScreen(BLACK);
   tft.setRotation(1);
  
 // Mostrar Tª Habitación
  tft.setTextSize(7);
  tft.setTextColor(WHITE);          
 //tft.fillRect(10, 0, 309,104, BLACK);
  tft.setCursor(20, 15);
   tft.print(T[0]);
  tft.println("C");
 
 tft.setTextSize(3);
  tft.setCursor(60,90);
  tft.setTextColor(WHITE);
  tft.println("Habitacion");


 // Mostrar Tª galeria
 tft.setTextSize(3);
  tft.setTextColor(YELLOW);
//  tft.fillRect(20, 160, 159,49, BLACK);
  tft.setCursor(10, 160);    

   tft.print(T[1]);         
  tft.println("C");

   tft.setTextSize(2);
  tft.setCursor(25, 200);
  tft.setTextColor(YELLOW);
  tft.println("Galeria");


 // Mostrar Tª exterior
 tft.setTextSize(3);
  tft.setTextColor(CYAN); 
  tft.setCursor(180, 160);      

   tft.print(T[2]);         
  tft.println("C");

    tft.setTextSize(2);
  tft.setCursor(190, 200);
  tft.setTextColor(CYAN);
  tft.println("Exterior");
  
waitOneTouch();

}


void lecturaD() {// Hacer grafica de temperaturas
   
short mx; //Maximo
short mn; //Minimo
float escala;

int x1;

    pinMode(XM, OUTPUT); //Pins configures again for TFT control
    pinMode(YP, OUTPUT);


  tft.setRotation(3);
   tft.fillScreen(BLACK);
       tft.setTextSize(2);
      
    mx=int(tp1[1]);      mn=int(tp1[1]); //Define máximos y mínimos

   for (tpp =0; tpp < 320; tpp = tpp+ 1) {          //Registro máximos y mínimos
    mx=max(mx,tp1[tpp]);    mn=min(mn,tp1[tpp]);
    mx=max(mx,tp2[tpp]);    mn=min(mn,tp2[tpp]);
    mx=max(mx,tp3[tpp]);    mn=min(mn,tp3[tpp]);
   }
   mx=mx+100;
if (mn>0){ mn=0; }
else {mn=mn-100;}

 //  mx=mx/100; mn=mn/100-1 ;
escala= 240/(float(mx)-float(mn)); // =240/(mx-mn)/100, alto/100

// dibujar escala
tft.setCursor(300,(0-mn)*(escala));
 tft.setTextSize(2);
  tft.setTextColor(RED);
  tft.println("0");
tft.drawFastHLine(0,((0-mn)*(escala)) , 319, RED); // Dibuja linea 0º

 for (x1=24; x1<= 288; x1 =x1+24) { tft.drawFastVLine(x1,0 , 239, GREEN);} // linea vertical cada 2H


 for (x1=-2500; x1<= 4500; x1 =x1+500) {                  // linea horizontal cada 5º
 if (x1!=0) {
   tft.setRotation(3);
  tft.drawFastHLine(0,((x1-mn)*(escala)), 319, BLUE);
 tft.setRotation(1);
 tft.setCursor(2,240-(x1-mn)*(escala)); // escribir graduación
  tft.setTextColor(BLUE);
  tft.println(x1/100);
 }
 }

 tft.setRotation(3);

   for (tpp =tp+1; tpp < 320; tpp = tpp+ 1) {  // representar 1ª parte de datos

        tft.fillCircle(319-(tpp-tp),(tp1[tpp]-mn)*(escala),1, WHITE);
                tft.fillCircle(319-(tpp-tp),(tp2[tpp]-mn)*(escala),1, CYAN);
                        tft.fillCircle(319-(tpp-tp),(tp3[tpp]-mn)*(escala),1, YELLOW);
}

    for (tpp =0; tpp < tp; tpp = tpp+ 1) {   // representar 2ª parte de datos
       
    tft.fillCircle((tp-tpp),(tp1[tpp]-mn)*(escala), 1, WHITE);
    tft.fillCircle((tp-tpp),(tp2[tpp]-mn)*(escala), 1, CYAN);
    tft.fillCircle((tp-tpp),(tp3[tpp]-mn)*(escala), 1, YELLOW);
}
delay(4000);
   waitOneTouch();
}


// Esperar pulsación

void waitOneTouch() {
int ciclo;
   TSPoint p;
  
       pinMode(XM, OUTPUT); //Pins configures again for TFT control
    pinMode(YP, OUTPUT);

  for (ciclo=0; ciclo<4000 br="" ciclo="ciclo+1){  " pausa="">    p= ts
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE){ // Detectar Pulsacion pantalla
     tone (45, 400, 180);
     MenuP(); 
     ciclo=4000;  }
  }
}


// Boton Activar termostato/ desactivar

void enc()
{
      if (optoac==0){
      texto="Apagar";
      optoac=1;
    }else{
      texto="Encender";
      optoac=0;
      digitalWrite(38,LOW);
    }
    MenuP();
}


//  Menu Fijar temp. Termostato
void termost()
{
////  digitalWrite(13, HIGH);
//  digitalWrite(13, LOW);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);

   //Menu
  tft.fillScreen(BLACK);
   tft.setRotation(1);
  
  tft.setTextSize(3);
  tft.setCursor(50, 2);
  tft.setTextColor(WHITE);
  tft.println("Termostato:");
  tft.setTextSize(9);
  tft.setCursor(30, 40);
  tft.println(termostato);
 
  tft.setTextSize(5);
  tft.setCursor(110, 140);
  tft.setTextColor(RED);
  tft.println("Subir");
  tft.setTextColor(CYAN);
  tft.setCursor(110, 200);
  tft.print("Bajar");
    tft.setRotation(0);

//  flechas
 tft.fillTriangle(70,22, 100, 57, 70,92, (RED));
 tft.fillTriangle(35, 22, 5, 57, 35, 92, (CYAN));

   termost2();
}

 
void termost2()
{  //  Captura de pulsación para fijar termostato
  int ciclo;
   TSPoint p;
  
  for (ciclo=0; ciclo<4000 br="" ciclo="ciclo+1){  " pausa="">  Serial.println(ciclo);
   p = ts.getPoint();
 
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
  {
    p.x = tft.width()-(map(p.x, TS_MINX, TS_MAXX, tft.width(), 0));
    p.y = tft.height()-(map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));
  
   tone (45, 400, 180);
  
      if (p.y <170 br="" de="" fija="" sale="" termostato="" y="">         {
         // delay(300);
           ciclo=4000;// volver al loop
                }
               
         else if (p.y <256 amp="" p.y=""> 170)  // Sube temp. termostato
         {
               if (termostato<28 termostato="termostato+0.2;}<br">               termost();
           ciclo=1000;
                  }
                 
         else if (p.y >256)    //Baja la temperatura del termostato
        
         {
           if (termostato>5) {termostato=termostato-0.2;}
           ciclo=1000;
           termost();
           }
    }
  }  // fin for ciclo
  tone (45, 400, 180) 

<--final br="">} 

<--final br="">// Fin del  sketch
<--final br="">//

jueves, 12 de mayo de 2016

Mini osciloscopio con arduino y LCD QC12864 (III). Conexión serie. (30Khz)

Antes de nada decir que tal y como compre yo mi lcd no podía comunicarse via serie con el arduino, tuve que desoldar un par de puentes que vienen en el display como resistencias 000.



Sé que en otros modelos no existe ese problema y si puede conectarse así sin ningún problema, en mi modelo no, el mío se quema si no se desuelda. No solo no se ve nada sino que además se quemaría.

En esta página explico lo que tuve que desoldar en mi modelo QC 12864B -1 se hace en un momento, deja libres 5 ó 6 pines frente a la conexión en paralelo, no hay perdidas aparentes de velocidad y puedes seguir conectandolo en paralelo si quieres  igual que siempre.  En el tiempo que yo llevo usandolo no he notado ningún inconveniente, por lo que me pregunto porque lo venderán inutilizado para la conexión en serie. :)

IMPORTANT! For this LCD to work using this method, you need to de-solder R9 and R11 at the back panel of the LCD.






La medición máxima es hasta 5V, puede protegerse el arduino con un zener,  Para medidas mayores debe usarse un divisor resistivo.

El conmutador permite cambiar entre dos modos de funcionamiento, osciloscopio o monitor, su resistencia es de 100Kohm.   
Los pulsadores sirven para aumentar o disminuir el tiempo de muestreo, la resistencia es de 10Kohm, aunque  en este caso si no se pone no pasa nada.

El potenciometro controla el contraste del LCD.

La máxima resolución en modo osciloscópio es de 5,5useg   y en modo monitor de .16 seg.





El programa está basado en la librería u8glib , que puede descargarse aquí y permite dibujar gráficos no sólo en el
QC12864, sino también en otros muchos modelos, tanto en conexión serie como paralelo.
Modificando el Delay del final el escanéo puede ser ralentizado.  La lectura que muestra es la que lee la entrada analógica, esto es entre 0 y 1024  que equivalen de  0 a 5V,


Sketch: DESCARGAR


#include "U8glib.h"

U8GLIB_ST7920_128X64_1X u8g(6, 5, 4 ,7);  //For ST7920_128X64  serie

 unsigned long sensor;  

int x;
int y[130];

 boolean monitor;

int y2;
unsigned long ycal;
// unsigned long tpo;

byte punto;
byte y3;

float mx;
byte mc;
byte fc;

int muestreo;
int boton=6;

void setup(void) {
  pinMode(3,INPUT);
   pinMode(2,INPUT);
     pinMode(10,INPUT);
 
attachInterrupt(0, mas, RISING); 
attachInterrupt(1, menos, RISING);

Serial.begin(9600);

}



void loop(void) {


  u8g.firstPage();

  //

monitor=(digitalRead(10));

  muestreo=boton*3;

Serial.println(monitor);

if (monitor==1) {    // Osciloscopio



  // Prescaler
   
   switch(byte(1+6*float(muestreo/400)))
  {
    case 0: //  =2 Malfuncionamiento
      bitWrite(ADCSRA,ADPS2,0);  bitWrite(ADCSRA,ADPS1,0);  bitWrite(ADCSRA,ADPS0,0);
    break;
    case 1:
     bitWrite(ADCSRA,ADPS2,0);  bitWrite(ADCSRA,ADPS1,1);  bitWrite(ADCSRA,ADPS0,0);
    break;
    case 2:
      bitWrite(ADCSRA,ADPS2,0);  bitWrite(ADCSRA,ADPS1,1);  bitWrite(ADCSRA,ADPS0,1);
    break;
    case 3:
    bitWrite(ADCSRA,ADPS2,1);  bitWrite(ADCSRA,ADPS1,0);  bitWrite(ADCSRA,ADPS0,0);
    break;
    case 4:
      bitWrite(ADCSRA,ADPS2,1);  bitWrite(ADCSRA,ADPS1,0);  bitWrite(ADCSRA,ADPS0,1);
    break;
    case 5:
      bitWrite(ADCSRA,ADPS2,1);  bitWrite(ADCSRA,ADPS1,1);  bitWrite(ADCSRA,ADPS0,0);
    break;
    case 6:
      bitWrite(ADCSRA,ADPS2,1);  bitWrite(ADCSRA,ADPS1,1);  bitWrite(ADCSRA,ADPS0,1);;
    break;
  }
 
 

  //Analog Input A0 
 ADMUX=(1<<ADLAR)|(0<<REFS1)|(1<<REFS0)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0); 
 


 // Lectura de datos


   if (muestreo <1 br="" muestreo="" nbsp="" turbo="">
     ycal = micros();


  y[0] = analogReadFast();  
    y[1] = analogReadFast();  
    y[2] = analogReadFast();  
    y[3] = analogReadFast();  
    y[4] = analogReadFast();  
    y[5] = analogReadFast();
    y[6] = analogReadFast();  
    y[7] = analogReadFast();  
    y[8] = analogReadFast();  
    y[9] = analogReadFast();  
    y[10] = analogReadFast();  
    y[11] = analogReadFast();  
    y[12] = analogReadFast();  
    y[13] = analogReadFast();  
    y[14] = analogReadFast();  
    y[15] = analogReadFast();  
    y[16] = analogReadFast();  
    y[17] = analogReadFast();  
    y[18] = analogReadFast();  
    y[19] = analogReadFast();  
        y[20] = analogReadFast();  
    y[21] = analogReadFast();  
    y[22] = analogReadFast();  
    y[23] = analogReadFast();  
    y[24] = analogReadFast();  
    y[25] = analogReadFast();  
    y[26] = analogReadFast();  
    y[27] = analogReadFast();  
    y[28] = analogReadFast();  
    y[29] = analogReadFast();
        y[30] = analogReadFast(); 
    y[31] = analogReadFast();  
    y[32] = analogReadFast();  
    y[33] = analogReadFast();  
    y[34] = analogReadFast();  
    y[35] = analogReadFast();  
    y[36] = analogReadFast();  
    y[37] = analogReadFast();  
    y[38] = analogReadFast();  
    y[39] = analogReadFast();
    y[40] = analogReadFast();
    y[41] = analogReadFast();  
    y[42] = analogReadFast();  
    y[43] = analogReadFast();  
    y[44] = analogReadFast();  
    y[45] = analogReadFast();  
    y[46] = analogReadFast();  
    y[47] = analogReadFast();  
    y[48] = analogReadFast();  
    y[49] = analogReadFast();
    y[50] = analogReadFast();  
    y[51] = analogReadFast();  
    y[52] = analogReadFast();  
    y[53] = analogReadFast();  
    y[54] = analogReadFast();  
    y[55] = analogReadFast();  
    y[56] = analogReadFast();  
    y[57] = analogReadFast();  
    y[58] = analogReadFast();  
    y[59] = analogReadFast();
    y[60] = analogReadFast();  
    y[61] = analogReadFast();  
    y[62] = analogReadFast();  
    y[63] = analogReadFast();  
    y[64] = analogReadFast();  
    y[65] = analogReadFast();  
    y[66] = analogReadFast();  
    y[67] = analogReadFast();  
    y[68] = analogReadFast();  
    y[69] = analogReadFast();
    y[70] = analogReadFast();  
    y[71] = analogReadFast();  
    y[72] = analogReadFast();  
    y[73] = analogReadFast();  
    y[74] = analogReadFast();  
    y[75] = analogReadFast();  
    y[76] = analogReadFast();  
    y[77] = analogReadFast();  
    y[78] = analogReadFast();  
    y[79] = analogReadFast();
    y[80] = analogReadFast();  
    y[81] = analogReadFast();;  
    y[82] = analogReadFast();  
    y[83] = analogReadFast();  
    y[84] = analogReadFast();  
    y[85] = analogReadFast();  
    y[86] = analogReadFast();  
    y[87] = analogReadFast();  
    y[88] = analogReadFast();  
    y[89] = analogReadFast();
    y[90] = analogReadFast();
    y[91] = analogReadFast();
    y[92] = analogReadFast();
    y[93] = analogReadFast();
    y[94] = analogReadFast();
    y[95] = analogReadFast();
    y[96] = analogReadFast();
    y[97] = analogReadFast();
    y[98] = analogReadFast();
    y[99] = analogReadFast();
 y[100] = analogReadFast();
    y[101] = analogReadFast();
    y[102] = analogReadFast();
    y[103] = analogReadFast();
    y[104] = analogReadFast();
    y[105] = analogReadFast();
    y[106] = analogReadFast();
    y[107] = analogReadFast();
    y[108] = analogReadFast();
    y[109] = analogReadFast();
    y[110] = analogReadFast();
    y[111] = analogReadFast();
    y[112] = analogReadFast();
    y[113] = analogReadFast();
    y[114] = analogReadFast();
    y[115] = analogReadFast();
    y[116] = analogReadFast();
    y[117] = analogReadFast();
    y[118] = analogReadFast();
    y[119] = analogReadFast();
    y[120] = analogReadFast();
    y[121] = analogReadFast();
    y[122] = analogReadFast();
    y[123] = analogReadFast();
    y[124] = analogReadFast();
    y[125] = analogReadFast();
    y[126] = analogReadFast();
    y[127] = analogReadFast();

  mx= (micros() - ycal);

}


else {    // muestreo con rapidez alta

  muestreo=muestreo-1;
 ycal = micros();

  for ( punto = 0; punto <= 127; punto++ ) {

    y[punto]=analogReadFast();
   
     delayMicroseconds(muestreo);
  }
 
  mx= (micros() - ycal);
   
  
  }

sensor = mx;   // tpo muestreo
 
  

  
       // fin muestro
       

 
  /// Estimación frecuencia   f= picos/tpo muestreo

     mx=0;
  
for ( punto = 0; punto <= 127; punto++ ) {
  
     mx=max(mx,y[punto]);
  
  }
 

 
  fc = 0;
 
  mx = mx*.9  ;  // Pico > 10%


  for ( punto = 0; punto <= 127; punto++ ) {

    if ( (mx < y[punto]) && (mc == 0)) {
      fc = fc + 1;
      mc = 1;
    }

    if (y[punto] < mx) {
      mc = 0;
    }
  }
}                          // <-- br="" cierre="" nbsp="" osciloscopio="">


else {                         // monitoreo del pin A0


mx=millis();
   y[128]=0; //media total

x=0;


  y[127]=analogRead(A0)/4;
  retardo();

  ycal=0;
  for ( punto = 0; punto <= 126; punto++ ) {
   
 y[punto]=y[punto+1];

      ycal=ycal+y[punto];
  }


  mx=millis()-mx;

y[128]=(ycal+y[127])/128;

}                    // cierre de monitoreo



  /// Dibujar

  do {

    draw();
  } while ( u8g.nextPage() );


  // delay(5000);   // Para congelar imagen entre muestreo y muestreo.
}  // fin loop



void retardo()   // retardo monitor
{

if (x<((170*(boton)))) {
    y[127]=((analogRead(A0)/4)+y[127])/2;
  x=x+1;
       delayMicroseconds(35);
retardo();
}

}

///////////////////    GRAFICA

void draw(void) {

  // graphic commands to redraw the complete screen should be placed here

  // u8g.drawFrame(0,0,128,56);  //marco exterior

  for ( punto = 21; punto <= 106; punto = punto + 42 ) {       // punto vertical cada 1V

    u8g.drawPixel(punto, 10);  u8g.drawPixel(punto, 21); u8g.drawPixel(punto, 32); u8g.drawPixel(punto, 43);

  }

 u8g.setFontPosTop();
 

  // Grafica de la onda

  y3 = 55 - 28 * float(y[0]) / 128;  ///  54/1024

  for ( punto = 1; punto <= 127; punto++ ) {


    ycal = 55 - 28 * float(y[punto]) / 128;    ///  54/1024


    u8g.drawLine(punto - 1, y3, punto, ycal);

    y3 = ycal;
  }


  // Leyenda

  u8g.setFont(u8g_font_04b_03);

  u8g.setPrintPos(0, 56);
 
  if (monitor==0){

    u8g.print(String(float(y[127])*5/256) +"V.  /"+ String(float(.16+mx/1000)) + " Seg.  Med: "+String(float(y[128])*5/256)+"V.");   ///   x5V
  }
  else {
    u8g.print( String(float((sensor+.5)/1000)) + " mSeg. /Estm: " + String(long(float(1000000*fc/(sensor+.5) ))) + " Hz ");
   }

}



//Read ADC
int analogReadFast()
{

ADCSRA|=(1<<ADSC);
 // ADSC is cleared when the conversion finishes
 while (bit_is_set(ADCSRA, ADSC));
        return ADCH;

}


void mas()  // aumentar tpo de muestreo
{
   if (boton<175 br="">       if (boton>15){
   boton=boton+5;
       }
       else
   {
    boton=boton+1;
   }
   }
}  


void menos()    // disminuir tpo de muestreo
{
  if (boton>0){
      if (boton>15){
   boton=boton-5;
      }
   else
   {
    boton=boton-1;
   }
   }
}

 



domingo, 27 de marzo de 2016

Mini osciloscopio con 2 arduino y QC12864. II (30Khz). Conexión paralelo.

En este post hacíamos un pequeño osciloscopio con un arduino nano y un lcd qc12864.
Tras comprobar las limitaciones de modificar el prescaler  en el arduino con casi todos sus pines analógicos trabajando, pensé en el otro pequeñín que tenía guardado en un cajón que podía ocuparse de hacer el muestreo de la señal, enviarselo al otro via serie que sería el encargado de los cálculos y la representación gráfica.
Al fin y al cabo los osciloscopios basados en arduino "más" decentes que he visto en internet funcionan así, aunque también hay otra opción con un solo arduino: conectarlos en serie.

De esta manera he logramos logrado una resolución de 6useg./pixel o lo que es lo mismo todo el ancho de pantalla menor de 1 milisegundo, con el potenciometro podemos variar la duración del muestreo hasta 200 mSeg. a partir de ahí el comportamiento del programa cambia y monitorea el valor de la señal.

El sketch viene preparado, descomentando una de las líneas finales del void(loop), para insertar un potenciometro al pin A7 y estabilizar la imagen, sobre todo en las frecuencias medias.



El funcionamiento del programa es similar al anterior, aunque ahora el arduino maestro envía una señal cuyo valor es la resolución requerida, tomada del potenciometro a través de A1, que a demás es la señal que indica al arduino esclavo que inicie el muestreo. ( Si hay un desajuste temporal, por ejemplo los encendemos en momentos distintos,  se va a quedar esperando esa señal indefinidamente, y habrá que reiniciar el arduino maestro para que coienze de nuevo - botón rset-).

Una vez hecho el muestreo se envían al maestro los datos a través del puerto serie, siendo el último dato el tiempo invertido en el muestreo, para que este los analice y represente en el lcd.

La lectura de la frecuencia es sólo una estimación y no es el propósito de este programa, aunque es bastante aproximada si vemos varias ondas en la pantalla,


Nuestro osciloscopio sólo admite valores de entrada entre 0 y +5V,  y otros valores lo pueden dañar, así que para visualizarlos  hay que usar divisores resistivos o  zener.



Para que funcionen  los sketch hay que tener instalada la librería U8glib.


Las conexiones son practicamente las mismas que en el osciloscopio anterior, con algunas pequeñas modificaciones para posibilitar la comunicación entre arduinos.




Los arduinos se conectan entre sí a través de los pines Tx y Rx con un cable cruzado, también deben compartir la masa, La señal se escanea a través del pin A0 del arduino esclavo.




Sketch 1. Arduino maestro (conectado al lcd) Descargar





#include "U8glib.h"


U8GLIB_ST7920_128X64_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);  //For ST7920_128X64 paralelo

unsigned long sensor;

int x;
int y[130];

boolean monitor;

int y2;
unsigned long ycal;

byte punto;
byte y3;

float mx;
byte mc;
byte fc;


void setup(void) {

  Serial.begin(115200);
}



void loop(void) {


  u8g.firstPage();

  // Envio del tpo de muestreo

  sensor = analogRead(A1)/2;
 

if (sensor < 256) {    // Osciloscopio

  monitor=0;
 
   if ( sensor <64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo="">

   Serial.write(byte(sensor));

 // Lectura de datos

  for ( punto = 0; punto <= 129; punto++ ) {
   
 while( Serial.available()==0){
 }

    y[punto] = Serial.read();
   
  
  }

sensor = (y[128]);   // tpo muestreo
 
   } // fin muestreo os. seg arduino
  

   else {   // muestreo propio arduino

   
y[129]=0;
mx=millis();


ycal=8*(sensor-64); // calibrado tiempo

 for ( punto = 0; punto <= 127; punto++ ) {  //muestreo pinA0 arduino maestro
    x=1;
    y[punto] = analogRead(A0);

  // delayMicroseconds(ycal);

   retardo0();

  }

 sensor= (millis()-mx)*4;
 
for ( punto = 0; punto <= 127; punto++ ) {
    y[punto] = y[punto]/4;
     y[129]=max(y[129],y[punto]);
  
  }
 
   
   }  // fin osciloscopio arduino  maestro

  
  /// Estimación frecuencia   f= picos/tpo muestreo

 
  fc = 0;
 
  mx = y[129]*.9  ;  // Pico > 10%


  for ( punto = 0; punto <= 127; punto++ ) {

    if ( (mx < y[punto]) && (mc == 0)) {
      fc = fc + 1;
      mc = 1;
    }

    if (y[punto] < mx) {
      mc = 0;
    }
  }
}                          // <-- br="" cierre="" nbsp="" osciloscopio="">

else {                         // monitoreo del pin A0

   monitor=1;

mx=millis();
   y[128]=0; //media total

x=100;


  y[127]=analogRead(A0)/4;
  retardo();
 
   for ( punto = 0; punto <= 126; punto++ ) {
   
 y[punto]=y[punto+1];

       y[128]=y[128]+y[punto];
  }


  mx=millis()-mx;

y[128]=y[128]/128;

}                    // cierre de monitoreo

  /// Dibujar

  do {

    draw();
  } while ( u8g.nextPage() );


//   delayMicroseconds(analogRead(A7)*50);   // Para congelar imagen entre muestreo y muestreo conviene controlar este parametro mediante potenciómetro.



}


void retardo0()    // retardo osciloscopio arduino maestro
{
   if (x   y[punto]=(analogRead(A0)+y[punto])/2;
  x=x+2;
     retardo0();
   }

}

void retardo()   // retardo monitor
{

if (x<((30*(analogRead(A1)-512)))) {
    y[127]=((analogRead(A0)/4)+y[127])/2;
  x=x+1;
retardo();
}

}

///////////////////    GRAFICA

void draw(void) {

  // graphic commands to redraw the complete screen should be placed here

  // u8g.drawFrame(0,0,128,56);  //marco exterior

  for ( punto = 21; punto <= 106; punto = punto + 42 ) {       // punto vertical cada 1V

    u8g.drawPixel(punto, 10);  u8g.drawPixel(punto, 21); u8g.drawPixel(punto, 32); u8g.drawPixel(punto, 43);

  }

 u8g.setFontPosTop();
 

  // Grafica de la onda

  y3 = 55 - 27 * float(y[0]) / 128;  ///  54/1024

  for ( punto = 1; punto <= 127; punto++ ) {


    ycal = 55 - 28 * float(y[punto]) / 128;    ///  54/1024


    u8g.drawLine(punto - 1, y3, punto, ycal);

    y3 = ycal;
  }


  // Leyenda

  u8g.setFont(u8g_font_04b_03);

  u8g.setPrintPos(0, 56);
 
  if (monitor==1){

    u8g.print(String(float(y[127])*5/255) +"V.  /"+ String(float(.17+mx/1000)) + " Seg.  Med: "+String(float(y[128])*5/255)+"V.");   ///   x5V
  }
  else {
    u8g.print( String(float((sensor+.5)/4)) + " mSeg. /Estm: " + String(long(float(fc / (sensor+.5) * 4000))) + " Hz ");
  }

}


<64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio="">
<64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio=""><64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio="">

<64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio="">
<64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio=""><64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio="">






Sketch 2. Arduino esclavo ( encargado de la obtención de datos.) Descargar

 


 void setup() {
  Serial.begin(115200);

    }

//////


void loop(void) {

byte punto;

byte y[130];

int sensor;

unsigned long ycal;


  // Muestreo

  
 while( Serial.available()==0){
 }    

   sensor=Serial.read();


 //Prescaler
  //ADPS2 - ADPS1 - ADPS0 - Division Factor
  //0       - 0      - 0         ->2
  //0       - 0      - 1         ->2
  //0       - 1      - 0         ->4    >
  //0       - 1      - 1         ->8    ***
  //1       - 0      - 0         ->16
  //1       - 0      - 1         ->32
  //1       - 1      - 0         ->64
  //1       - 1      - 1         ->128
 
 // A partir de 4 funciona bien, el 2 distorsiona mucho. Cuanto más subimos el osciloscopio es más lento pero más preciso

switch(byte(1+6*sensor/64))
  {
    case 0: //  =2  distorsionado
      bitWrite(ADCSRA,ADPS2,0);  bitWrite(ADCSRA,ADPS1,0);  bitWrite(ADCSRA,ADPS0,0);
    break;
    case 1:
     bitWrite(ADCSRA,ADPS2,0);  bitWrite(ADCSRA,ADPS1,1);  bitWrite(ADCSRA,ADPS0,0);
    break;
    case 3:
      bitWrite(ADCSRA,ADPS2,0);  bitWrite(ADCSRA,ADPS1,1);  bitWrite(ADCSRA,ADPS0,1);
    break;
    case 4:
    bitWrite(ADCSRA,ADPS2,1);  bitWrite(ADCSRA,ADPS1,0);  bitWrite(ADCSRA,ADPS0,0);
    break;
    case 5:
      bitWrite(ADCSRA,ADPS2,1);  bitWrite(ADCSRA,ADPS1,0);  bitWrite(ADCSRA,ADPS0,1);
    break;
    case 6:
      bitWrite(ADCSRA,ADPS2,1);  bitWrite(ADCSRA,ADPS1,1);  bitWrite(ADCSRA,ADPS0,0);
    break;
    case 7:
      bitWrite(ADCSRA,ADPS2,1);  bitWrite(ADCSRA,ADPS1,1);  bitWrite(ADCSRA,ADPS0,1);;
    break;
 
  }

 
  //Analog Input A0
ADMUX=(1<<ADLAR)|(0<<REFS1)|(1<<REFS0)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);



 sensor=sensor*1.2;

  if (sensor ==0) {
  

///  MUESTREO turbo

 ycal = micros();

  //


  y[0] = analogReadFast();
  
    y[1] = analogReadFast();
  
    y[2] = analogReadFast();
  
    y[3] = analogReadFast();
  
    y[4] = analogReadFast();
  
    y[5] = analogReadFast();
  
    y[6] = analogReadFast();
  
    y[7] = analogReadFast();
  
    y[8] = analogReadFast();
  
    y[9] = analogReadFast();
  
    y[10] = analogReadFast();
  
    y[11] = analogReadFast();
  
    y[12] = analogReadFast();
  
    y[13] = analogReadFast();
  
    y[14] = analogReadFast();
  
    y[15] = analogReadFast();
  
    y[16] = analogReadFast();
  
    y[17] = analogReadFast();
  
    y[18] = analogReadFast();
  
    y[19] = analogReadFast();
  
        y[20] = analogReadFast();
  
    y[21] = analogReadFast();
  
    y[22] = analogReadFast();
  
    y[23] = analogReadFast();
  
    y[24] = analogReadFast();
  
    y[25] = analogReadFast();
  
    y[26] = analogReadFast();
  
    y[27] = analogReadFast();
  
    y[28] = analogReadFast();
  
    y[29] = analogReadFast();

        y[30] = analogReadFast();
  
    y[31] = analogReadFast();
  
    y[32] = analogReadFast();
  
    y[33] = analogReadFast();
  
    y[34] = analogReadFast();
  
    y[35] = analogReadFast();
  
    y[36] = analogReadFast();
  
    y[37] = analogReadFast();
  
    y[38] = analogReadFast();
  
    y[39] = analogReadFast();
        y[40] = analogReadFast();
  
    y[41] = analogReadFast();
  
    y[42] = analogReadFast();
  
    y[43] = analogReadFast();
  
    y[44] = analogReadFast();
  
    y[45] = analogReadFast();
  
    y[46] = analogReadFast();
  
    y[47] = analogReadFast();
  
    y[48] = analogReadFast();
  
    y[49] = analogReadFast();
    y[50] = analogReadFast();
  
    y[51] = analogReadFast();
  
    y[52] = analogReadFast();
  
    y[53] = analogReadFast();
  
    y[54] = analogReadFast();
  
    y[55] = analogReadFast();
  
    y[56] = analogReadFast();
  
    y[57] = analogReadFast();
  
    y[58] = analogReadFast();
  
    y[59] = analogReadFast();
    y[60] = analogReadFast();
  
    y[61] = analogReadFast();
  
    y[62] = analogReadFast();
  
    y[63] = analogReadFast();
  
    y[64] = analogReadFast();
  
    y[65] = analogReadFast();
  
    y[66] = analogReadFast();
  
    y[67] = analogReadFast();
  
    y[68] = analogReadFast();
  
    y[69] = analogReadFast();
        y[70] = analogReadFast();
  
    y[71] = analogReadFast();
  
    y[72] = analogReadFast();
  
    y[73] = analogReadFast();
  
    y[74] = analogReadFast();
  
    y[75] = analogReadFast();
  
    y[76] = analogReadFast();
  
    y[77] = analogReadFast();
  
    y[78] = analogReadFast();
  
    y[79] = analogReadFast();
        y[80] = analogReadFast();
  
    y[81] = analogReadFast();
  
    y[82] = analogReadFast();
  
    y[83] = analogReadFast();
  
    y[84] = analogReadFast();
  
    y[85] = analogReadFast();
  
    y[86] = analogReadFast();
  
    y[87] = analogReadFast();
  
    y[88] = analogReadFast();
  
    y[89] = analogReadFast();
        y[90] = analogReadFast();
  
    y[91] = analogReadFast();
  
    y[92] = analogReadFast();
  
    y[93] = analogReadFast();
  
    y[94] = analogReadFast();
  
    y[95] = analogReadFast();
  
    y[96] = analogReadFast();
  
    y[97] = analogReadFast();
  
    y[98] = analogReadFast();
  
    y[99] = analogReadFast();
 y[100] = analogReadFast();
  
    y[101] = analogReadFast();
  
    y[102] = analogReadFast();
  
    y[103] = analogReadFast();
  
    y[104] = analogReadFast();
  
    y[105] = analogReadFast();
  
    y[106] = analogReadFast();
  
    y[107] = analogReadFast();
  
    y[108] = analogReadFast();
  
    y[109] = analogReadFast();
  
    y[110] = analogReadFast();
  
    y[111] = analogReadFast();
  
    y[112] = analogReadFast();
  
    y[113] = analogReadFast();
  
    y[114] = analogReadFast();
  
    y[115] = analogReadFast();
  
    y[116] = analogReadFast();
    y[117] = analogReadFast();
    y[118] = analogReadFast();
    y[119] = analogReadFast();
    y[120] = analogReadFast();
    y[121] = analogReadFast();
    y[122] = analogReadFast();
    y[123] = analogReadFast();
    y[124] = analogReadFast();
    y[125] = analogReadFast();
    y[126] = analogReadFast();
    y[127] = analogReadFast();

  y[128]= (micros() - ycal)/250;

}

else {    // muestreo con retardo
 
 ycal = micros();

  for ( punto = 0; punto <= 127; punto++ ) {


    y[punto]=analogReadFast();
   

    delayMicroseconds(sensor);
  }
  y[128]= (micros() - ycal)/250;
}


  // ENVIO al  otro arduino

  for ( punto = 0; punto <= 127; punto++ ) {
   
  y[129]=max(y[129],y[punto]);  //Pico
   Serial.write(y[punto]);
    
  }
  Serial.write(y[128]); Serial.write(byte(y[129]));


    y[129]=0; // Pico

}

 //Read ADC
int analogReadFast()
{
ADCSRA|=(1<<ADSC);
 // ADSC is cleared when the conversion finishes
 while (bit_is_set(ADCSRA, ADSC));
        return ADCH;
}


domingo, 29 de noviembre de 2015

Monitoreo sensor de distancia con Qc12864-B

   SKETCH



    #include "U8glib.h"
   

    U8GLIB_ST7920_128X64_1X u8g(6, 5, 4 ,7); // CONEXION SERIE
 
   
  
    float sensor=1025 ;
   
    byte x;
    float y[128];
    byte punto;
    long distancia;
long tiempo;
   
    void draw(void) {
      // graphic commands to redraw the complete screen should be placed here 
     
    u8g.drawFrame(0,0,128,56);
      u8g.setFont(u8g_font_04b_03);
      u8g.setFontPosTop();
    u8g.drawStr(0, 56, "Distanc:");
    u8g.setFontPosTop();
   
    // punto
   
for( punto = 1; punto <= 127; punto++ ) {
  
   u8g.drawPixel(punto,55-54*y[punto]/1024);


}
    // barra de nivel
   
    u8g.drawFrame(32,57,75,6);
    u8g.drawBox(33,58,74*(sensor/1024),4);
    u8g.setColorIndex(0);
    u8g.drawBox(33+74*(sensor/1024),58,73-74*(sensor/1024),4);
    u8g.setColorIndex(1);
    //u8g.drawFrame(32,57,75,6);
   
    //leyenda
     
   
     String s =  String(int( distancia)) ;
       
 u8g.setPrintPos(109, 56);
  u8g.print(s);
 //  u8g.drawStr(109, 56, s);
     }
   
    void setup(void) {
 //      Serial.begin(9600);

pinMode(9, OUTPUT); /*activación del pin 9 como salida: para el pulso ultrasónico*/
  pinMode(8, INPUT); /*activación del pin 8 como entrada: tiempo del rebote del ultrasonido*/
         
                  
    }
   
    void loop(void) {
      // picture loop
   
   u8g.firstPage();  

       digitalWrite(9,LOW); /* Estabilización del sensor*/
  delayMicroseconds(5);
  digitalWrite(9, HIGH); /* envío del pulso */
  delayMicroseconds(10);
  tiempo=pulseIn(8, HIGH);
  distancia= int(0.017*tiempo);
     
   
      sensor=1024*distancia/338;
    
    // 
    x= x+1;
    if (x>=126) {
     x=1;
     }
    y[x]=(sensor);

   
    for( punto = 1; punto <= 127; punto++ ) {

    }
    //  // rebuild the picture after some delay
      do {
        draw();
      } while( u8g.nextPage() );
   
   
     
   
   
     // delay(100);
    }




CONEXIONES:
IMPORTANTE: Para conectar en serie con el arduino y no quemar nada tube que desoldar dos resistencias como indico aquí. No hay que hacelo con todos los LCD, pero con mi modelo de lcd de no hacerlo se puede quemar.


lunes, 16 de noviembre de 2015

Monitoreo de un sensor con QC12864-B y arduino.(Conexión serie.)




En este caso, por  simplicidad y dejar libre el mayor número de pines, hemos utilizado comunicación serie entre el arduino y el LCD.  En mi modelo, el QC1286-B-1, para poder hacerlo hay que quitar un par de resistencias de 0 Ohmios de la trasera del LCD: R9 y R11, y esto es importante porque de no hacerlo estaremos puenteando los 5V con masa y en el mejor de los casos no va a funcionar, y en el peor nos  cargaremos el arduino y/o el LCD. 

IMPORTANT! For this LCD to work using this method, you need to de-solder R9 and R11 at the back panel of the LCD.

Por lo que he visto en internet, en la misma pagina donde saqué la información del desoldado  , en otros proyectos podremos seguir usando nuestro LCD en modo paralelo uniendo el pin PSD  a la salida 5V, tal y como se hacía con otros modelos anteriores de QC12864 . (5V+.conexión paralelo y a masa para serie). Quien tenga uno de los  modelos más antiguos no va a tener  que hacerles nada porque ya vienen sin el puenteo de estas resistencias.






También puede usarse en modo paralelo, por lo que se gana algo en velocidad, pero tan poca que no merece la pena sacrificar esos 8 pines ni el cableado, como ventaja no hay que desoldar nada, pero las conexiones que yo indico en el esquema  para paralelo no sirven y habrá que hacer otras, también utilizará 7 ó 8  pines más del arduino, de ahí la conveniencia de usar la conexión en serie.



Conexiones.


Para simular el sensor he representado un potenciómetro, el de arriba de la imagen. El de la parte inferior será de 10K y sirve para elegir el contraste adecuado.

La foto de los pines es la parte trasera del LCD, lo que queda abajo, entonces una vez apollada en el protoboard la parte de arriba corresponde con la derecha del esquema de conexiones y la de abajo con la izquierda.

 





El sketch
El programa está basado en la librería u8glib , que puede descargarse aquí y permite dibujar gráficos no sólo en el
QC12864, sino también en otros muchos modelos, tanto en conexión serie como paralelo.
Modificando el Delay del final el escanéo puede ser ralentizado.  La lectura que muestra es la que lee la entrada analógica, esto es entre 0 y 1024  que equivalen de  0 a 5V,



      https://www.youtube.com/watch?v=pQ-HUbdc4Cg
    #include "U8glib.h"
  

    U8GLIB_ST7920_128X64_1X u8g(6, 5, 4 ,7);  // For ST7920_128X64  serie - QC12864
    //     U8GLIB_ST7920_128X64_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);  //For ST7920_128X64   paralelo
  
    float sensor=1025 ;
  
    byte x;
    float y[128];
    float y2;
    float ycal;
    byte punto;
  
    void draw(void) {
    
      // graphic commands to redraw the complete screen should be placed here
    
    u8g.drawFrame(0,0,128,56);
      u8g.setFont(u8g_font_04b_03);
      u8g.setFontPosTop();
    u8g.drawStr(0, 56, "Sensor:");
    u8g.setFontPosTop();
  
    // punto
  
for( punto = 1; punto <= 127; punto++ ) {
 
   ycal=55-54*y[punto]/1024;
   u8g.drawLine(punto-1,y2,punto,ycal);

 y2=ycal;
}
    // barra de nivel
  
    u8g.drawFrame(32,57,75,6);
    u8g.drawBox(33,58,74*(sensor/1024),4);
    u8g.setColorIndex(0);
    u8g.drawBox(33+74*(sensor/1024),58,73-74*(sensor/1024),4);
    u8g.setColorIndex(1);

  
    // Lectura en número    
  
     String s =  String(int( sensor)) ;
      
 u8g.setPrintPos(109, 56);
  u8g.print(s);

     }



    ////////////////////
  
    void setup(void) {

    
      // assign default color value
      if ( u8g.getMode() == U8G_MODE_R3G3B2 )
        u8g.setColorIndex(255);     // white
      else if ( u8g.getMode() == U8G_MODE_GRAY2BIT )
        u8g.setColorIndex(3);         // max intensity
      else if ( u8g.getMode() == U8G_MODE_BW )
        u8g.setColorIndex(1);         // pixel on
  
                 
    }
  
    void loop(void) {
      // picture loop
  
   u8g.firstPage(); 

   
         //u8g.prepare();
       
      sensor=analogRead(A0);
   
    //   Posición x


    for( x= 0; x <= 126; x++ ) {
    y[x]= y[x+1];
  
         }
       
    y[127]=(sensor);

/// Dibujar

      do {
        draw();
      } while( u8g.nextPage() );
 
  
     // delay(100);
    }