Afficheur hdsp2000 avec dht22

bonjour,
utilisaton de hdsp2000 : matrice 5x7 leds x 4 série

le code croquis vient de cette page :
CROQUIS

il est long je le mets en supprimant la table de caracteres inutile pour la compréhension

#include <Wire.h>

//*** HDSP2000 Display Demo
//*** ASCII-DEMO
//*** phuinink@gmail.com  : liens morts 2024
//*** Paul Huinink has a webpage on displays www.huinink.info and specifically HDSP200X series displays www.spagmon.com
//*** Modified December-2013 by Patrick Hickey: added HP HDSP single digit display and RGB LED
//*** Patrick Hickey ph@nipht.com

//modified 3/2018 by Brandon McRee - removed support for LED and single digit HDSP DISPLAY
// 

//figure out latch pin

// an array of 5 bytes per ASCII
// 5 bytes cause 5 columns
// 7 bits per column (no LSB)


const byte ascii_5x7[] = {    //when I put this in PROGMEM i get gibberish, without it the SRAM is 87% full... 
    table caracteres
};

int column[] = {2, 3, 4, 5, 6}; // can change to other pins 
int data = 7;   // change this to other general input/output arduino-pins as you like
int clock = 8;  // change this to other general input/output arduino-pins as you like


int brightness = 2000; // keep high for max visibility. To high will cause flikkering 

const int numberOflDisplays = 2; // change this if total number of HDSP200x's is different.

int tekstDat[numberOflDisplays * 4 * 5]; // this is the array that store's what on the displays. 4 digits per display and 5 columns per digit.

unsigned long tijd; // used to trigger events in one of the examples below

char buf[40];
boolean flagRx = false; //allowed to receive if false

//*****************************************************************setup*************************************************************
void setup(){
    //Serial.begin(9600);

    for (int i = 0; i < 5; i++){
        pinMode(column[i], OUTPUT);
    }
    for (int i = 0; i < 5; i++){
        digitalWrite(column[i], LOW);
    }
    pinMode(data, OUTPUT);
    pinMode(clock, OUTPUT);
    digitalWrite(data, LOW); 
    digitalWrite(clock, HIGH);
    tijd = millis();

    Wire.begin(8);        // join i2c bus with address #8  >>important<<
    Wire.onReceive(receiveEvent); // register event
    // sais pas ce qui concerne le bus i2c
}

//***********************************************************************************end setup******************************************************

void loop(){


    char PROGMEM clr[] = "    ";
    char PROGMEM scroll[]  = "2024 TECH CONTROL PANEL ";
    char PROGMEM scroll2[] = "Remember Stupid... you have to drive this home :)"; 
    // ne reprend pas l'affichage apres 1 tour de loop
    // on est a la limite de la memoire ram
    if(flagRx == false){
        delay(10); //needs this delay to be stable
        scrollText(scroll, 40); //scrolling text, speed : second number is var howslow how slow this is a test of fastdraw text (short strings)
        delay(1000); 
        scrollText(scroll2, 40);
        delay(10);          
        flagRx = true; // can now recieve    
    }
    else{
        writeText(buf);
        for (int i = 0; i< 50; i++) draw(); //does this continuously - display HDSP2011

    } 
    /*
            scrollText(scroll3, 10);
            delay(10);


        //short quick text write
        scrollText(hello, 8); 
        scrollText(world, 8);
        delay(500); 


            delay(5);
        writeText("TEST") ;                   //letters only? special charachters
        for (int i = 0; i< 100; i++) draw();
                delay(5);
        writeText("ABCDEFGHIJKLMNOPQRSTUVWXYZ") ; 
        for (int i = 0; i< 70; i++) draw();
                delay(5);
        writeText("1234567890") ;
        for (int i = 0; i< 100; i++) draw();
                delay(5);
        writeText("!@#$%^&*()") ;
        for (int i = 0; i< 50; i++) draw(); //delay??
                delay(5); 

        delay(1000);       


            */      


    writeText(buf);
    for (int i = 0; i< 50; i++) draw(); //does this continuously 

}
//****************end of main loop *********************************

void receiveEvent(int howMany) {

    int i;
    for (i=0; i<howMany; i++){      
        buf[i] = Wire.read(); //read I2C data (address 8)
    }

    flagRx = true;    // set flag, we received something. will figure out how to clear when

    // while (1 < Wire.available()) { // loop through all but the last     



}

//int x = Wire.read();    // receive byte as an integer not used
//Serial.println(x);          // print the integer



void writeDigit(int positie, int ascii){
    for (int i =0; i< 5;i++){
        tekstDat[(numberOflDisplays * 4 - positie) * 5 + i] = ascii_5x7[ascii*5+i];
    }
}

void scrollText(String tekkst, long howSlow){
    int leng = tekkst.length();
    for (int u=-numberOflDisplays*4;u<leng;u++){ // first N digits will be spaces. N = all digits of display. So one screen blank before first character apears.
        for (int v=0; v< numberOflDisplays*4;v++){
            if (( (u+v) >= 0 ) && ((u+v) < leng)){ // separete leading and tailing spaces from actual string
                char oneChar= tekkst.charAt(u+v);
                writeDigit(v+1, oneChar); // write the character of the string
            }
            else{
                writeDigit(v+1, 32); // write ascii-value 32 = a space.
            }
        }
        for (long teller = 0; teller < howSlow; teller++){
            draw();   
        }
    }
}

void writeText(String tekst){
    int tl = tekst.length();
    int spacesNeeded = 4 * numberOflDisplays - tl;
    if (spacesNeeded <0){
        tl = 4 * numberOflDisplays;    
    }
    else{
        for (int u = 0; u < spacesNeeded; u++){
            tekst.concat(" ");
        }
        tl = 4 * numberOflDisplays;    
    }
    char tekst_[tl];
    for (int vv = 0; vv < tl; vv++){
        char tt = tekst.charAt(tl-vv-1);
        for (int i =0; i< 5;i++){
            //tekstDat[vv*5+i] = ascii_5x7[tt*5+i]; //old using SRAM
            //tekstDat[vv*5+i] = (pgm_read_byte(ascii_5x7))[tt*5+i]; //new  try and read from PROGMEM does not compile :/
        }
    }
}

void dot(byte x, byte y, boolean oo){
    if ((x < (numberOflDisplays *4 * 5)) && (y < 7)){
        byte oldByte = tekstDat[x] & (0xFF - (2<<y));
        tekstDat[x] = oldByte | (2<<y);
    }
}

void draw(){
    for (int Kolom = 0; Kolom < 5; Kolom++){ // 5 columns to be strobed
        // pumping in 3 x 4 x 7 bits per one stobe of the column
        for (int displayNo = 0; displayNo < numberOflDisplays; displayNo++){  // number of  displays
            for (int digitNo = 0; digitNo < 4; digitNo++){ // 4 characters per display
                for (int diodeNo = 0; diodeNo < 7; diodeNo++){ // 7 row-elements
                    digitalWrite(clock, HIGH);
                    digitalWrite(data, tekstDat[Kolom + 5*(displayNo*4 + digitNo) ] &(2<<diodeNo)); // magic
                    digitalWrite(clock, LOW);
                }
            }
        }
        digitalWrite(column[Kolom], HIGH);
        delayMicroseconds(brightness);
        digitalWrite(column[Kolom], LOW);
    }
}

c'est le falgRx qui passe à true dans le loop et qui bloque apres 1 "tour" ?
l'adresse i2c 0x08 : c'est pour relier 2 uno en I2C ?
dans la loop j'ai commenté le flagRx = true; et la loop tourne "normalement"

comment utiliser la fonction "receiveEvent" ?

je ne vois pas d'explications sur la page en lien, et les liens donnés dans l'en tete du croquis sont morts, sa video youtube est toujours en ligne

remarques : la table de caracteres se trouve en ram, dans la page en lien 1 personne donne un "truc" pour mettre la table en pgmem ? comment ?
dans la note d'application de hp/avago de 1999, conseille de mettre la table dans une mémoire externe avec un schéma, on est en 1999 et une usine à gaz.....
ces afficheurs ont été récupérés sur des appareils spécifiques mis au rebut en 1996, a base de 8031

Merci pour toutes infos

C'est à dire, en quoi le fonctionnement initial du programme que tu as récupéré n'est pas normal ?

Qu'appel tu bloquer?
une fois que la variable passe à vrai, tu n'affichera plus les deux chaines initiales scroll et scroll2
d'ailleurs je ne suis pas sûr que le "else" soit necessaire car ca duplique le code qui si.

Donc une fois les deux chaines en mode scrolling ont été affiché, tu affiche ce que tu reçois sur l'I2C.
Mais on ne sait pas ce que tu as branché sur l'I2C de ton Arduino.
On ne sait pas non plus quel est ton schéma et ce que tu es sensé recevoir par l'I2C.

j'ai trouvé un autre croquis qui utilise beaucoup moins de memoire ram, la table de caracteres est un fichier h

reste à trouver comment lui faire afficher les data d'un capteur quelconque
croquis origine modifié pour test

#include "font.h"

int column[] = {2, 3, 4, 5, 6}; 
int data = 7;   
int clock = 8;
int brightness = 2000; 
const int cntDisplays = 2; // j'ai 2 hdsp2000 connectés
int txtData[cntDisplays * 4 * 5]; // this is the array that store's what on the displays. 4 digits per display and 5 columns per digit.
int p;
int cod;

void setup() {
  for (int i = 0; i < 5; i++) {
    pinMode(column[i], OUTPUT);
  }
  for (int i = 0; i < 5; i++) {
    digitalWrite(column[i], LOW);
  }
  pinMode(data, OUTPUT);
  pinMode(clock, OUTPUT);
  digitalWrite(data, LOW);
  digitalWrite(clock, HIGH);
}

void loop() {
  //char PROGMEM scroll[]  = "arduino";
 // writeText(scroll);
  // scrollText(scroll,30);
  
  for (p = 1; p< 9 ; p++){
  writeDigit(p, (47+p)); // (position, code ascii)
  // affiche 01234567
  draw();  // mettre directement dans la fonction ? 
                         }
  
}  //endloop

void writeDigit(int position, int ascii) {
  for (int i = 0; i < 5; i++) {
    txtData[(cntDisplays * 4 - position) * 5 + i] = ascii_5x7[ascii * 5 + i];
  }
}

void scrollText(String txt, long howSlow) {
  int leng = txt.length();
  for (int u = -cntDisplays * 4; u < leng; u++) { 
    for (int v = 0; v < cntDisplays * 4; v++) {
      if (( (u + v) >= 0 ) && ((u + v) < leng)) { 
        char oneChar = txt.charAt(u + v);
        writeDigit(v + 1, oneChar); 
      }
      else {
        writeDigit(v + 1, 32); 
      }
    }
    for (long teller = 0; teller < howSlow; teller++) {
      draw();
    }
  }
}

void writeText(String txtShow) {
  int tl = txtShow.length();
  int spacesNeeded = 4 * cntDisplays - tl;
  if (spacesNeeded < 0) {
    tl = 4 * cntDisplays;
  }
  else {
    for (int u = 0; u < spacesNeeded; u++) {
      txtShow.concat(" ");
    }
    tl = 4 * cntDisplays;
  }
  char txtShow_[tl];
  for (int vv = 0; vv < tl; vv++) {
    char tt = txtShow.charAt(tl - vv - 1);
    for (int i = 0; i < 5; i++) {
    }
  }
}

void draw() {
  for (int columnDisp = 0; columnDisp < 5; columnDisp++) { 
    for (int displayNr = 0; displayNr < cntDisplays; displayNr++) { 
      for (int digitNr = 0; digitNr < 4; digitNr++) { 
        for (int diodeNr = 0; diodeNr < 7; diodeNr++) { 
          digitalWrite(clock, HIGH);
          digitalWrite(data, txtData[columnDisp + 5 * (displayNr * 4 + digitNr) ] & (2 << diodeNr)); 
          digitalWrite(clock, LOW); 
        }
      }
    }
    digitalWrite(column[columnDisp], HIGH);
    delayMicroseconds(brightness); 
    digitalWrite(column[columnDisp], LOW);
  }
}

Merci

Du coup quel est le problème ou la question ?

bonjour,

la question : afficher les données d'un capteur
fait pour un dht22, hormis que j'ai 8 caracteres qui se suivent sur la meme ligne çà fait 19.744.1
le truc embetant : on ne peut pas faire delay et figer l'affichage pendant un certain temps sinon l'affichage reste éteint et n'apparait que le temps de la fonction affichage, j'ai mis une boucle qui repete la fonction X fois avec les memes valeurs avant de retourner "lire" le dht22,
je n'ai pas besoin de decimale pour l'humidité, un espace entre temp et hum et le symbole %
comme 19.7 44%, ou mettre 2 lignes de 8 caractères
TEMP 19.7
HUM 44%

çà n'intéresse personne, c'est normal, des composants vintage qui coutaient une fortune à l'époque, le max7219 tres utilisé encore aujourd'hui existe depuis 30 ans...

merci aux lecteurs

Je ne comprends pas bien cette phrase.
Pourquoi au juste tu veut faire une delay pour figer l'affichage, si tu ne veux pas modifier l'affichage pendant un certain temps, il suffit de ne pas demander un nouvelle affichage pendant ce temps ?
Du coup lorsque tu met un delay, ton affichage s'efface ?

Tu as une température de cette forme 19.744.1 ??
à quoi correpsond le deuxième "."

Cet afficheur doit être rafraîchi en permanence.

Oui, c'est ce que je supposais, mais je voulais avoir une confirmation et j'avais la flemme d'aller regarder la datasheet :slight_smile:

T'aurais pas été mordu par Lapino par hasard?

Je ne crois pas, mais avec ce genre de virus qui sait :rofl:

bonjour,
chaque digit est constitué d'une matrice de 5 colonnes x7 leds, l'affichage doit etre rafraichi en permanence, le "brightness" est une valeur introduite dans la fonction draw en delaymicroseconds
pour une luminosité en fonction de la persistance rétinienne,


le hdsp2000 à une pin Vled (que j'ai mis sur 3v3) qui pourrait commander la luminosité avec une broche pwm pilotant un transistor moyenne puissance
un croquis avec dht22
un croquis avec horloge ds3231
reste a combiner les 2 pour afficher la temperature toutes les 10 minutes pendant 15 secondes

Je ne comprends pas ce qui te bloque.

Si tu sais faire afficher une chaîne de caractères, tu peux aussi bien en faire afficher une autre.
Il suffit juste de modifier périodiquement la chaîne à faire afficher.

bonjour,
pour répondre au post #6 affiche temperature et humidité sur la ligne à la suite, le 2eme "." est la décimale du float humidité
j'ai du convertir les float en String pour l'affichage, je met le code dht22 temp hum, si il y a une autre méthode pour afficher les float et pour éliminer la décimale de h ?
Merci

// ok 15/03/24  todo : 2 lignes 8 caracteres ou separer les 2 hdsp 4digits

#include "font.h"
#include <string.h>
// la lib DHT n'est pas celle qu'on trouve 9x sur 10
#include <DHT22.h>  // https://github.com/nethoncho/Arduino-DHT22
//define pin dht
#define pinDATA 9 
DHT22 dht22(pinDATA); 

int column[] = {2, 3, 4, 5, 6}; 
int data = 7;   
int clock = 8;
int brightness = 2000; 
const int cntDisplays = 2; // j'ai 2 hdsp2000 connectés
int txtData[cntDisplays * 4 * 5]; // this is the array that store's what on the displays. 4 digits per display and 5 columns per digit.
//int p;
//int cod;
//const char PROGMEM errtxt[]  = "erreur";
const char errtxt[]  = "erreur";
String ptexte ="TEMP";
String htexte ="HUM ";

void setup() {
  Serial.begin(115200);
  
  for (int i = 0; i < 5; i++) {
    pinMode(column[i], OUTPUT);
  }
  for (int i = 0; i < 5; i++) {
    digitalWrite(column[i], LOW);
  }
  pinMode(data, OUTPUT);
  pinMode(clock, OUTPUT);
  digitalWrite(data, LOW);
  digitalWrite(clock, HIGH);
}

void loop() {
  char temptxt[4]; 
  char humtxt[4];
  //char totatxt[8];
  
  float t = dht22.getTemperature();
  float h = dht22.getHumidity();
    // il faut convertir le float t en String avec une décimale
    // et le float h en String sans décimale
// test si dht22 ok
      if (dht22.getLastError() != dht22.OK) {
    writeText(errtxt);
    return;
  }

// afficher t et h avec la fonction writeDigit ou writeText
String tempASstring;
dtostrf (t, 4, 1, temptxt);
tempASstring = String(temptxt);

String humASstring;
dtostrf (h, 4, 1, humtxt);
humASstring = String(humtxt);
//String totatxt = tempASstring+humASstring; // aff temp+hum sur 1 ligne
String totatxt = ptexte+tempASstring; // aff TEMP t
for (int i=0; i<100; i++) {
  writeText(totatxt);  }  //  la boucle for
  // repete la fonction 100x avant de continuer
 String totatxt2 = htexte+humASstring;
 for (int i=0; i<20; i++) {
  writeText(totatxt2);  } 
  // repete la fonction 20x avant de retourner ou debut du loop
        }  //endloop

void writeDigit(int position, int ascii) {
  for (int i = 0; i < 5; i++) {
    txtData[(cntDisplays * 4 - position) * 5 + i] = ascii_5x7[ascii * 5 + i];
  }
}

// fonction non utilisee dans ce croquis
void scrollText(String txt, long howSlow) {
  int leng = txt.length();
  for (int u = -cntDisplays * 4; u < leng; u++) { 
    for (int v = 0; v < cntDisplays * 4; v++) {
      if (( (u + v) >= 0 ) && ((u + v) < leng)) { 
        char oneChar = txt.charAt(u + v);
        writeDigit(v + 1, oneChar); 
      }
      else {
        writeDigit(v + 1, 32); 
      }
    }
    for (long teller = 0; teller < howSlow; teller++) {
      draw();
    }
  }
}

void writeText(String txtShow) {
  int tl = txtShow.length();
  int spacesNeeded = 4 * cntDisplays - tl;
  if (spacesNeeded < 0) {
    tl = 4 * cntDisplays;
  }
  else {
    for (int u = 0; u < spacesNeeded; u++) {
      txtShow.concat(" ");
    }
    tl = 4 * cntDisplays;
  }
  char txtShow_[tl];
  for (int vv = 0; vv < tl; vv++) {
    char tt = txtShow.charAt(tl - vv - 1);
    for (int i = 0; i < 5; i++) { 
      txtData[vv*5+i] = ascii_5x7[tt*5+i];
      //txtData[vv*5+i] = (pgm_read_byte(ascii_5x7))[tt*5+i];
      draw(); 
    }
  }
}

void draw() {
  for (int columnDisp = 0; columnDisp < 5; columnDisp++) { 
    for (int displayNr = 0; displayNr < cntDisplays; displayNr++) { 
      for (int digitNr = 0; digitNr < 4; digitNr++) { 
        for (int diodeNr = 0; diodeNr < 7; diodeNr++) { 
          digitalWrite(clock, HIGH);
          digitalWrite(data, txtData[columnDisp + 5 * (displayNr * 4 + digitNr) ] & (2 << diodeNr)); 
          digitalWrite(clock, LOW); 
        }
      }
    }
    digitalWrite(column[columnDisp], HIGH);
    delayMicroseconds(brightness); 
    digitalWrite(column[columnDisp], LOW);
  }
}

ok, quelque chose comme le code ci-dessous

  char s[16];
  snprintf(s, 16, "%.2f %i", t, (int)h);

Mais plus globalement si tu veux enlever la décimal, tu peux juste convertir le float en int, ce qui correspond à tronquer.
Si tu veux avoir un arrondis plus conventionnel, Arduino possède la macro round

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.