reset an spi connection? pb with max7219

Posted on
  • Hello, i'm working with a cheap chinese 8x8 led matrix mounted with a Max7219.
    sometime ( i'm enable to determine when or why, can't reproduce bug). the display go weird... it show only one line or 2 lines of pix... after a time it come back good.
    if i unplug/replug the board (a pico) everything restart well.
    in first i was thinking about a prob with the graphic buffer but when i ask to show content it look full of datas...
    therfore i was thinking a prob with the display...

    is it possible to reduce the spi baudrate and in wich value?
    or to reset an spi connection?
    do i need to find an other matrix with better chip... an idea?

    ps: i'm testing with low data transfer to display and it seem to work well (show on display one time on 10)
    i'have a second timer with a led pulse...

    regards

    require("Font4x6").add(Graphics);
    // spi mosi=DIN, sck=CLOCK
    SPI2.setup({mosi:B15, sck:B13});
    // crée le buffer graphique 8x8 en 1 bit
    var g = Graphics.createArrayBuffer(8,8,1);
    // connecte en spi
    var disp = require("MAX7219").connect(SPI2, B14);
    
    var texte = "Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.";
    
    var phrase = texte.substr(0,12);
    var sDerCar = phrase.substr(10,2);
    var cPhrase = 0;
    var compteur = 8;
    var longT = 0;
    var lengthT = texte.length;
    var longP = 0;
    var decalage = 0;
    var debut = false;
    var val=0;
    var step = 5;
    
    function sendData() {
      // raccorde le bout de ligne suivant
      if (compteur < -longP+decalage+1){
        if (debut) {compteur = 8; debut=false;console.log("debut");} else {compteur = 0;}
        cPhrase++;
        // si au bout du texte
        phrase= texte.substr(cPhrase*10,12);
        sDerCar = phrase.substr(10,2);
        decalage = g.stringWidth(sDerCar);
        console.log("decalage:",decalage);
        if (decalage === 0) {
          // on est en fin de texte, à la prochaine boucle, on reprend le texte au début
          cPhrase=-1;
          debut = true;
          console.log("redemarrage texte");
        }
      }
    
      // reset le buffer, ajoute la font, ecrit la chaine de caractères
      g = Graphics.createArrayBuffer(8,8,1);
      g.setFont4x6();
      /* une fois font utilisée, on connait la longueur de la chaine*/
      longP = g.stringWidth(phrase);
      // calcul le decalage (en pix) entre chaque bout de phrase
      decalage = g.stringWidth(sDerCar);
      g.drawString(phrase,compteur,0);
      // envoie à la matrice
      disp.intensity(0.2);
      disp.raw(g.buffer);
      compteur--;
    }
    
    function led() {
      /* var val= Math.random();
        if (val<.5) {val = 0;}*/
      //console.log(val);
      calc = Math.sin(val/100);
      analogWrite(A5, Math.abs(calc),{freq:300});
      val+=step;
      if (val>314) {val = 0; step=(Math.random()*8)+1;}
    }
    function onInit() {
      console.log("init programme - éric choisy ©2018");
      setInterval(sendData, 60);
      setInterval(led, 10);
      }
    
  • i have a long text to display, so i've subdivised text by piece of 10 chars to reduce mem usage and time to drawString in the arrayBuffer... (code look complexe and not optimised)
    sorry

  • I did not completely see thru your code, but mainly, there is a heave function and a much lighter function, each independent of each other and called on individual intervals.

    What is going on here is to understand from the point of how Espruino works, or in other words, how event driven JavaScript environment works.

    First, though, let's look at the code - especially at the on init:

    Every 60 ms, sendData() is invoked,
    Every 10 ms, led() is invoked.

    If you put console.log into your code, you will see that 5 or 6 times led() runs before sendData() is run the first time. Also, when you put console.log at begin and end as first and last in led() and sendData(), you will notice that one always runs completely before it runs again or something else runs (completely).

    To make it bette visible, change the time to a least the 10 fold: 600 and 100 ms, that way Espruino can - most of the time - take care of what it is told to do before a new time event happens and the same ore something else should happen.

    JavaScript is executed as single thread. No things will go in parallel at any time. A time event (or event through a sensor on a pin from outside) create an even/interrupt in the event/interrupt queue in the primary or hardware run cycle. It is called primary because it is closest to the hardware - pin change, timer event - overrun/underrun/0-crossing) - happens and has higher priority then JavaScript execution. When all these high prioritized events/interrupts have been served and respective event with its data/context package is written to the JavaScript event/interrupt queue, the primary cycle goes into idle... but the processor is now free to take care of the events that were put into the JavaScript event queue. The processor 'starts'/resumes the work of interpreting JavaScript: for each entry in the JavaScript is invoked. In your case, led()... and led() again, etc. until sendData() is encountered and worked on. Now it may be that it cannot finish that within 10ms, so led() has and does wait until the processor gets free again for pickup.

    Even though both of your functions called at intervals have nothing to do with each other, they can have an impact on each other. Do you know how much time it take to execute sendData()? Adding getTime() at begin and end with delta calculation will tell you.,

    You may see the effect of the internal JavaScript Event Queue to overflow, even though it is decently sized to handle bursts, but continuous pounding.

  • Hello @allObjects,
    thanks for your advice.
    the first timer (sendDatas) need between 18 and 20 ms to achieve.
    i rewrote the code with only one timer and a trigger (a seesaw).
    each time it play led, one in two it send datas to display.
    the timer is banging at 30ms (so under the sendDatas() needs)
    I've started a test.

  • @allObjects why do you think it is a transcription from another langage?
    I use example provided in the max7219's module. And build in js. I iterate code writing step by step so the structure is durty (i'm pretty sure there is useless var)
    Yes i'm not dev, just designer, and therfore i'm not thinking as a dev. ;)

    I've rewrote with a setTimeout.
    If i well anderstand, there is no parallel process and instructions are worked one by one. Therefore if i restart a function at the end of the same function,it will restart after everythink is done. No?
    Except if spi transfer is asynchronous. Is it?

  • ...a transcription

    The loop puzzled me and also the double setInterval(). ...but as you noticed, I had withdrawn it right after initial/partial post. NM.

    If you restart a function at the end with a setTimeout() (with a time dependent, calculated/variable) tiemout time), you are fine, because this gives the system time to answer things that may have queued up. Chopping up bit work helps in that respect.

    Regarding spi transfer being asynchronous, I'm not sure. I assume that it is some what and when it is, it still has a buffer that may overflow... It is for sure implemented natively - not in JS - in order to act timely, especially when it is soft spi. Being natively implemented and considerate of the Espruino context, I expect it on higher priority - can interrupt JS process - but is 'knows' what JS can do to the system and behaves accordingly (managing variables, buffer, etc).

  • So the problem persist, time to time... I suppose spi is asynchronous...
    Therfore I've added a reboot() at the end of each cycle (all text done and led cycle done)
    The spi is reinitialized and every thing look good. And there is no messe on the display.
    I suppose i can do in an other way by adding more time to the first line, it seems, it's at a restart (when substring displayed (my cursor) go back to beginning) which the prob issue.

    Thanks for your help.

  • Is it possible that it's actually to do with wiring? Do you have GND properly connected between the controller and the MAX7219?

    Or how long are the wires you're using? An 8x8 LED matrix at 5v can draw a lot of power, so with long, thin wires the voltage drop can be enough that you get communications issues.

    You can easily change the baud rate if needed though: http://www.espruino.com/Reference#l_SPI_­setup

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

reset an spi connection? pb with max7219

Posted by Avatar for Mrbbp @Mrbbp

Actions