Gamoover

[move]Bienvenue sur Gamoover, portail francophone de l'arcade.

[WIP] Réalisation d'un déguisement pour mon fils

Démarré par tilowil, Lundi 31 Mars 2014, 23:23:13 PM

spectroman

super, ça prend forme.

c'est quoi le bug que l'on voit sur les colonnes 1 & 5 de la deuxième matrice?

c'est un problème de câblage?

Little_Rabbit

Salut,

Citation de: tilowil le Jeudi 03 Avril 2014, 07:57:13 AM
Allez la vidéo (elle dure 10 minutes) et j'ai écrit intentionnellement l'animation que je vais jouer.

Et bien, pour quelqu'un qui débuterait en programmation d'arduino, tu te débrouilles comme un chef !!  ^-

Quelques petites remarques perso :
- je jouerais toutes les animations 2 fois plus vite, ce serait plus dynamique je trouve
- pour le mode Cylon, je ferais l'oeil un peu plus épais et plus large :) (éventuellement, en réduisant la largeur quand l'oiel arrive aux extrémités droite et gauche - je ne sais pas si je sui très clair ! :) )
- le mode SD est superbe, j'adore !
- pour le mode equalizer, j'aurais plus vu des barres qui ne bougent pas sur l'axe des X, qui partent du bas et montent à des hauteurs variables en se raccourcissant avec un amorti, un peu comme l'equalizer de Winamp :) (bon OK, plus facile à dire qu'à faire ! ;))

Mais bon, chapeau encore une fois  ^- !

A+
Recherche bornes dédiées ou PCB originaux: Miss Pacman, Dig Dug, Galaga, Mappy, Asteroids, Battlezone, Missile Command, Tempest, Star Wars, Donkey Kong (+ Jr), Mario Bros, Moon Patrol, Defender, Joust, Frogger, Gyruss, Pooyan, Space Tactics, Zaxxon, etc. Flip : Gottlieb des années 80 (Spirit, Amazon Hunt, ...), Baby Pac Man. Divers :  Ice Cold Beer => Trois fois rien quoi ! :D
Ma séance sur le divan : c'est grave Docteur ? :-\
Ma gaming room, ma storage room

tilowil

#18
Citation de: spectroman le Jeudi 03 Avril 2014, 08:31:28 AM
super, ça prend forme.

c'est quoi le bug que l'on voit sur les colonnes 1 & 5 de la deuxième matrice?

c'est un problème de câblage?
Merci,

Oui c'est apparu quand j'ai échangé mes boitiers (remplacer les Max7221 par les AS1107). J'ai peut être un boitier défectueux. Je dois faire l'échange avec un autre (en premier permuter le 1 et le 2 pour voir si le défaut se déplace) et si l'échange ne suffit pas, procéder à un remplacement.

Citation de: Little_Rabbit le Jeudi 03 Avril 2014, 09:50:59 AM
Salut,

Et bien, pour quelqu'un qui débuterait en programmation d'arduino, tu te débrouilles comme un chef !!  ^-

[...]

Mais bon, chapeau encore une fois  ^- !

A+
Merci Little mais tu vas me faire rougir. L'arduino c'est de la programmation C like, ça va je connais, il a juste fallu apprendre les adressages des sorties. c'est un joujou fort intéressant d'ailleurs.

Concernant tes remarques :
Citation de: Little_Rabbit le Jeudi 03 Avril 2014, 09:50:59 AM
- je jouerais toutes les animations 2 fois plus vite, ce serait plus dynamique je trouve
la vitesse dépend du nombre de modules que je met en oeuvre, avec 3 modules c'est superbe, mais avec 5 j'ai ce ralentissement. Il faut que je travaille pour accélérer l'affichage, mais je ne sais pas encore comment faire.

Citation de: Little_Rabbit le Jeudi 03 Avril 2014, 09:50:59 AM
- pour le mode Cylon, je ferais l'oeil un peu plus épais et plus large :) (éventuellement, en réduisant la largeur quand l'oiel arrive aux extrémités droite et gauche - je ne sais pas si je sui très clair ! :) )
Oui tu es clair :D. je me suis taté pour cette animation d'abord je voulais le faire de la hauteur de la matrice, mais quand j'ai re visionné une video des cylons je me suis dit qu'un carre de 2x2 devrait être suffisant. En plus le casque sera chromé ce qui est ressemblant aux Cylons  =:)).

Aprèsje veux bien essayer ton idée, mais j'ai peur que ce soit trop gros. Je le programme en animation Cylon2 et je te fais une petite video.

Citation de: Little_Rabbit le Jeudi 03 Avril 2014, 09:50:59 AM
- le mode SD est superbe, j'adore !
Merci  <:). Mais la aussi la multiplication des modules ma fait au début une animation pas terrible. J'ai du renforcé la génération des étoiles en mettant une génération aléatoire de 5 étoiles au lieu 1 comme j'avais prévu au début.

Citation de: Little_Rabbit le Jeudi 03 Avril 2014, 09:50:59 AM
- pour le mode equalizer, j'aurais plus vu des barres qui ne bougent pas sur l'axe des X, qui partent du bas et montent à des hauteurs variables en se raccourcissant avec un amorti, un peu comme l'equalizer de Winamp :) (bon OK, plus facile à dire qu'à faire ! ;))
Je dois corriger cette animation car il y a un bug. Effectivement ce que j'avais prévu les barres reposent sur l'axe des X et montent et descendent suivant des valeurs tirées aléatoirement. Il n'y aura que 5 barres (1 par matrice).

tilowil

#19
Petite avancée ce matin.
Le parasitage que j'avais sur la seconde matrice venais du boitier AS1107, je l'ai mis en premier et le parasite s'est déplacé sur la première matrice. Donc j'ai changé le boitier (j'en avais commandé 10 pour une utilisation de 5, mais j'ai d'autres projets pour les restants) et maintenant l'affichage est nickel.

Pour faire plaisir au petit lapin j'ai créée Cylon2


j'en ai profité pour corriger le vu metre (toujours pour faire plaisir au petit lapin)


ensuite pour vous faire comprendre la problématique de vitesse voici 2 essais
En utilisation 3 modules


en utilisation 5 modules (utilisation normale pour mon besoin)


donc pour essayer d'aller plus vite j'ai mis un step de 2 (mais c'est moche)


pour finir pour ceux qui voudrait une base de depart je vous laisse le code de ma programmation

AS1107.CPP

/*
  AS1107.cpp
*/
#include <avr/pgmspace.h>
#include "Arduino.h"
#include "AS1107.h"

const byte AS1107::_repcharoff  = 27;

// Font Data
PROGMEM prog_uchar _font[] = {
    // -------- Space
    0b00000000,
    0b00000000,
    0b00000000,
    0b00000000,
    // -------- A
    0b01111110,
    0b10010000,
    0b10010000,
    0b01111110,
    // -------- B
    0b01101100,
    0b10010010,
    0b10010010,
    0b11111110,
    // -------- C
    0b10000010,
    0b10000010,
    0b01111100,
    // -------- D
    0b00111000,
    0b01000100,
    0b10000010,
    0b11111110,    
    // -------- E
    0b10000010,    
    0b10010010,    
    0b11111110,
    // -------- F
    0b10000000,        
    0b10010000,        
    0b11111110,
    // -------- G
    0b01011100,      
    0b10010010,
    0b10000010,
    0b01111100,
    // -------- H
    0b11111110,
    0b00010000,
    0b00010000,
    0b11111110,    
    // -------- I
    0b10000010,    
    0b11111110,    
    0b10000010,    
    // -------- J
    0b11111100,    
    0b00000010,
    0b00001100,
    // -------- K
    0b10000110,    
    0b01001000,    
    0b00110000,
    0b11111110,
    // -------- L
    0b00000010,      
    0b00000010,      
    0b11111110,
    // -------- M
    0b11111110,
    0b01100000,
    0b00111100,      
    0b01100000,      
    0b11111110,
    // -------- N
    0b11111110,
    0b00011000,
    0b01100000,      
    0b11111110,    
    // -------- O
    0b01111100,
    0b10000010,
    0b10000010,
    0b01111100,      
    // -------- P
    0b01100000,    
    0b10010000,
    0b10010000,
    0b11111110,
    // -------- Q
    0b01111010,
    0b10000100,
    0b10001010,
    0b01111100,    
    // -------- R
    0b01100110,      
    0b10011000,
    0b10010000,
    0b11111110,
    // -------- S
    0b10001100,
    0b10010010,
    0b01100010,    
    // -------- T
    0b10000000,      
    0b11111110,
    0b10000000,      
    // -------- U
    0b11111100,
    0b00000010,
    0b00000010,
    0b11111100,      
    // -------- V
    0b11000000,
    0b00111000,
    0b00000110,
    0b00111000,
    0b11000000,      
    // -------- W
    0b11111110,
    0b00001100,
    0b00111000,      
    0b00001100,      
    0b11111110,    
    // -------- X
    0b11000110,
    0b00111000,
    0b00111000,    
    0b11000110,
    // -------- Y
    0b11100000,
    0b00011110,
    0b11100000,    
    // -------- Z
    0b11000010,
    0b10110010,
    0b10001110,      
    // -------- Unknown character (#255)
    0b00111000,      
    0b00111000,
    0b00111000,
    // -------- 0
    0b01111100,
    0b10100010,
    0b10010010,
    0b01111100,      
    // -------- 1
    0b11111110,
    0b01000000,
    // -------- 2
    0b01100010,
    0b10010010,
    0b10001110,      
    // -------- 3
    0b01101100,
    0b10010010,
    0b10000010,      
    // -------- 4
    0b11111110,
    0b00010000,
    0b11110000,      
    // -------- 5
    0b10001100,
    0b10010010,
    0b11110010,      
    // -------- 6
    0b01001100,
    0b10010010,
    0b10010010,
    0b01111100,      
    // -------- 7
    0b11100000,
    0b10011110,
    0b10000000,      
    // -------- 8
    0b01101100,
    0b10010010,
    0b10010010,
    0b01101100,      
    // -------- 9
    0b01111100,
    0b10010010,
    0b10010010,
    0b01100100,      
    // -------- :
    0b00100100,
    // -------- ;
    0b00100110,
    0b00000001,
    // -------- !
    0b01100000,
    0b11111010,
    0b01100000,
    // -------- Heart (#)
    0b01111000,
    0b11111100,
    0b11111110,
    0b01111111,
    0b11111110,
    0b11111100,
    0b01111000,
    // -------- <
    0b01000100,
    0b00101000,
    0b00010000,
    // -------- =
    0b00101000,
    0b00101000,
    0b00101000,
    0b00101000,
    // -------- >
    0b00010000,
    0b00101000,
    0b01000100,
    // -------- ?
    0b01100000,
    0b10011010,
    0b10000000,
    // -------- @
    0b01111100,
    0b10000010,
    0b10111010,
    0b10100010,
    0b01011100,
    // -------- (
    0b10000010,
    0b01111100,
    // -------- )
    0b01111100,
    0b10000010,
    // -------- *
    0b00101000,
    0b00010000,
    0b00101000,
    // -------- +
    0b00010000,
    0b00010000,
    0b01111100,
    0b00010000,
    0b00010000,
    // -------- ,
    0b00000110,
    0b00000001,  
    // -------- -
    0b00010000,
    0b00010000,
    0b00010000,
    0b00010000,
    // -------- .
    0b00000010,
    // -------- /
    0b11000000,
    0b00111000,
    0b00000110,
    // -------- a
    0b00111110,
    0b00100010,
    0b00100010,
    0b00011100,
    // -------- b
    0b00011100,
    0b00100010,
    0b00100010,
    0b11111110,
    // -------- c
    0b00100010,
    0b00100010,
    0b00011100,
    // -------- d
    0b11111110,
    0b00100010,
    0b00100010,
    0b00011100,
    // -------- e
    0b00011000,
    0b00101010,
    0b00101010,
    0b00011100,
    // -------- f
    0b10010000,
    0b01111110,
    0b00010000,
    // -------- g
    0b00111110,
    0b00100101,
    0b00100101,
    0b00011000,
    // -------- h
    0b00011110,
    0b00100000,
    0b00100000,
    0b11111110,
    // -------- i
    0b00000010,
    0b01011110,
    0b00010010,
    // -------- j
    0b01011110,
    0b00000001,
    0b00000001,
    // -------- k
    0b00100010,
    0b00010100,
    0b00001000,
    0b11111110,
    // -------- l
    0b00000010,
    0b11111100,
    // -------- m
    0b00011110,
    0b00100000,
    0b00111110,
    0b00100000,
    0b00111110,
    // -------- n
    0b00011110,
    0b00100000,
    0b00100000,
    0b00111110,
    // -------- o
    0b00011100,
    0b00100010,
    0b00100010,
    0b00011100,
    // -------- p
    0b00001100,
    0b00010010,
    0b00010010,
    0b00011111,
    // -------- q
    0b00011111,
    0b00010010,
    0b00010010,
    0b00001100,
    // -------- r
    0b00010000,
    0b00100000,
    0b00111110,
    // -------- s
    0b00100100,
    0b00101010,
    0b00101010,
    0b00010010,
    // -------- t
    0b00100010,
    0b11111100,
    0b00100000,
    // -------- u
    0b00111110,
    0b00000010,
    0b00000010,
    0b00111100,
    // -------- v
    0b00111000,
    0b00000110,
    0b00111000,
    // -------- w
    0b00111110,
    0b00000010,
    0b00011110,
    0b00000010,
    0b00111100,
    // -------- x
    0b00110110,
    0b00001000,
    0b00110110,
    // -------- y
    0b00111110,
    0b00000101,
    0b00000101,
    0b00111001,
    // -------- z
    0b00110010,
    0b00101010,
    0b00100110,
    0b00100010,
    // -------- Empty Heart ($)
    0b01111000,
    0b10000100,
    0b10000010,
    0b01000001,
    0b10000010,
    0b10000100,
    0b01111000,
    // -------- Mickey Head (%)
    0b01101100,
    0b01110110,
    0b00011110,
    0b00011110,
    0b01110110,
    0b01101100,
    0b00000000,
    // -------- Skull (&)
    0b01111000,
    0b11011110,
    0b11011100,
    0b11110110,
    0b11011100,
    0b11011110,
    0b01111000,
    // -------- Eye(])
    0b00010000,
    0b00111000,
    0b01111100,
    0b00000110,
    0b00011010,
    0b00011010,
    0b00000110,
    0b01111100,
    0b00111000,
    0b00010000,
    // ---------- Eye([)
    0b00010000,
    0b00111000,
    0b00111100,
    0b00100100,
    0b00011000,
    0b00011000,
    0b00100100,
    0b00111100,
    0b00111000,
    0b00010000    
};


// Char width table
PROGMEM prog_uchar _charwidth[] = {4,4,4,3,4,3,3,4,4,3,3,4,3,5,4,4,4,4,4,3,3,4,5,5,4,3,3,
                                   3,4,2,3,3,3,3,4,3,4,4,1,2,3,7,3,4,3,3,5,2,2,3,5,2,4,1,
                                   3,4,4,3,4,4,3,4,4,3,3,4,2,5,4,4,4,4,3,4,3,4,3,5,3,4,4,
                                   7,7,7,10,10,0 };

// ASCII Codes of the implemented characters                                    
PROGMEM prog_uchar _charcodes[] = {32,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
                                   81,82,83,84,85,86,87,88,89,90,255,48,49,50,51,52,53,
                                   54,55,56,57,58,59,33,35,60,61,62,63,64,40,41,42,43,44,
                                   45,46,47,97,98,99,100,101,102,103,104,105,106,107,108,
                                   109,110,111,112,113,114,115,116,117,118,119,120,121,
                                   122,36,37,38,93,91,0};
// ------------------------------------------------------------------------------------
// Constructor, initialize arduino
AS1107::AS1107(byte cspin, byte clkpin, byte datapin)
{
  _cspin = cspin;
  _clkpin = clkpin;
  _datapin = datapin;
  pinMode(cspin, OUTPUT);
  pinMode(clkpin, OUTPUT);
  pinMode(datapin, OUTPUT);
  digitalWrite(cspin,HIGH);
  digitalWrite(clkpin,LOW);
  digitalWrite(datapin,LOW);
}

// ------------------------------------------------------------------------------------
// Initializes Arduino and AS1107
// buffer is the initial screen buffer
void AS1107::Init(byte * buffer)
{
  _buffer = buffer;
  CalculateCharOffsets();
  // Clear Screen buffer
  Clear();
  for (int i=0; i<=HighestCtrlNum; i++) {
    WriteRegister(i, Registers::Shutdown, ShutdownModes::Normal);
    WriteRegister(i, Registers::DecodeMode, 0x00);
    WriteRegister(i, Registers::IntensityControl, 0x00);
    WriteRegister(i, Registers::ScanLimit, 0x07);
  }
}

// ------------------------------------------------------------------------------------
// Set the Screen buffer
void AS1107::SetBuffer(byte * buffer)
{
  _buffer = buffer;
}

// ------------------------------------------------------------------------------------
// Writes Data to a Register of the AS1106/AS1107
// chip: Number of the controller chip (starting at 0 for the left)
// reg:  Register of the controller
// data: Data to be written
void AS1107::WriteRegister( byte chip, byte reg,  byte data)
{
  if (chip>=0 && chip <= HighestCtrlNum) {
    chip = HighestCtrlNum -chip;
    digitalWrite(_cspin,LOW);
    for (int i=0; i<=HighestCtrlNum; i++) {
    if (i == chip) {
      shiftOut(_datapin, _clkpin, MSBFIRST, reg);
      shiftOut(_datapin, _clkpin, MSBFIRST, data);
    }
    else {
      shiftOut(_datapin, _clkpin, MSBFIRST, Registers::NoOp);
      shiftOut(_datapin, _clkpin, MSBFIRST, 0);
    }
  }
    digitalWrite(_cspin,HIGH);
  }
}

// ------------------------------------------------------------------------------------
// Writes a column of data to the LED-Matrix
// column: column number, starting at 0
// data  : screen data to be written
void AS1107::WriteColumn( byte column,  byte data)
{
  // if you use unusual matrix row wiring, you can manipulate data here
  byte chip = (column) >>3;
  byte reg = (column % 8) +1;
  WriteRegister(chip, reg, data);
}

// ------------------------------------------------------------------------------------
// Sets the status of a LED in the screen buffer
void AS1107::SetLed(int x, int y, byte value)
{
  if (x<=Maxx && y<=Maxy && x>=0 && y>=0) {
    if (value>0) value = 1;
    SetLedInternal(x, y, value);
 }
}
void AS1107::SetLedD(int x, int y, byte value)
{
  if (x<=Maxx && y<=Maxy && x>=0 && y>=0) {
    if (value>0) value = 1;
    SetLedInternalD(x, y, value);
 }
}

// ------------------------------------------------------------------------------------
// Writes Buffer to Screen
// needs to be called after a graphics operation to see anything
void AS1107::Update()
{
  for (byte i=0; i<=Maxx; i++) {
    WriteColumn(i, _buffer[i]);
  }
}

// ------------------------------------------------------------------------------------
// Clear the Screen Buffer
void AS1107::Clear()
{
  for (byte i=0; i<=Maxx; _buffer[i++]=0);
}

// ------------------------------------------------------------------------------------
// Shift the content of the Screen buffer to the left
void AS1107::ShiftLeft()
{
  for (byte i=1; i<=Maxx; i++) {
    _buffer[i-1] = _buffer[i];
  }
  _buffer[Maxx] = 0;
}
// ------------------------------------------------------------------------------------
// Shift the content of the Screen buffer to the right
void AS1107::ShiftRight()
{
  for (byte i=Maxx; i>=1; i--) {
    _buffer[i] = _buffer[i-1];
  }
  _buffer[0] = 0;
}
// ------------------------------------------------------------------------------------
// Shift the content of the Screen buffer up
void AS1107::ShiftUp()
{
  for (byte i=0; i<=Maxx; i++) {
    _buffer[i] = _buffer[i]<<1 & 0xFE;
  }
}
// ------------------------------------------------------------------------------------
// Shift the content of the Screen buffer up
void AS1107::ShiftUp(byte from, byte to)
{
  for (byte i=from; i<=to; i++) {
    _buffer[i] = _buffer[i]<<1 & 0xFE;
  }
}
// ------------------------------------------------------------------------------------
// Shift the content of the Screen buffer down
void AS1107::ShiftDown()
{
  for (byte i=0; i<=Maxx; i++) {
    _buffer[i] = _buffer[i]>>1 & 0x7F;
  }
}
// ------------------------------------------------------------------------------------
// Shift the content of the Screen buffer down
void AS1107::ShiftDown(byte from, byte to)
{
  for (byte i=from; i<=to; i++) {
    _buffer[i] = _buffer[i]>>1 & 0x7F;
  }
}
// ------------------------------------------------------------------------------------
// draws a line from x0 ,y0 to x1,y1
void AS1107::DrawLine(int x0, int y0, int x1, int y1)
{

  int dx =  abs(x1-x0), sx = x0<x1 ? 1 : -1;
  int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1;
  int err = dx+dy, e2; /* error value e_xy */

  for(;;){  /* loop */
    SetLed(x0,y0,ON);
    if (x0==x1 && y0==y1) break;
    e2 = 2*err;
    if (e2 >= dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */
    if (e2 <= dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */
  }
}
// ------------------------------------------------------------------------------------
// erase a line from x0 ,y0 to x1,y1
void AS1107::EraseLine(int x0, int y0, int x1, int y1)
{

  int dx =  abs(x1-x0), sx = x0<x1 ? 1 : -1;
  int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1;
  int err = dx+dy, e2; /* error value e_xy */

  for(;;){  /* loop */
    SetLedD(x0,y0,OFF);
    if (x0==x1 && y0==y1) break;
    e2 = 2*err;
    if (e2 >= dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */
    if (e2 <= dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */
  }
}
// ------------------------------------------------------------------------------------
// draws a box from x0,x0 to x1,y1
void AS1107::DrawBox(int x0, int y0, int x1, int y1)
{
  DrawLine(x0,y0,x1,y0);
  DrawLine(x1,y0,x1,y1);
  DrawLine(x1,y1,x0,y1);
  DrawLine(x0,y1,x0,y0);
}
// ------------------------------------------------------------------------------------
// draws an ellipse
// center xm, ym   - radius a,b
void AS1107::DrawEllipse(int xm, int ym, int a, int b)
{
   if (a ==0 && b== 0) {
  SetLed(xm,ym,ON);
  return;
   }

   int dx = 0, dy = b; /* first quadrant from top left to bottom right */
   int a2 = a*a, b2 = b*b;
   int err = b2-(2*b-1)*a2, e2; /* error value in the first step */

   do {
     SetLed(xm+dx, ym+dy, ON); /* I. Quadrant */
     SetLed(xm-dx, ym+dy, ON); /* II. Quadrant */
     SetLed(xm-dx, ym-dy, ON); /* III. Quadrant */
     SetLed(xm+dx, ym-dy, ON); /* IV. Quadrant */

     e2 = 2*err;
     if (e2 <  (2*dx+1)*b2) { dx++; err += (2*dx+1)*b2; }
     if (e2 > -(2*dy-1)*a2) { dy--; err -= (2*dy-1)*a2; }
   } while (dy >= 0);

   while (dx++ < a) { /* correction for flat ellipses (b=1) */
     SetLed(xm+dx, ym, ON);
     SetLed(xm-dx, ym, ON);
   }
}

// ------------------------------------------------------------------------------------
// Writes Text at a screen position
void AS1107::DrawText (int x, int y, char *str)
{
  byte count;
  char thechar;
  while (*str != '\0') {
    x+=DrawChar(x, y, *str);
    str++;
  }
}

// ------------------------------------------------------------------------------------
// Draws a single character at a screen position
// returns the x-position for the next character
byte AS1107::DrawChar (int x, int y, char thechar)
{
  y+=7;
  byte charnum, colct, count=0, colbits;
  int fontidx;
  charnum = GetInternalCharCode(thechar);

  // get the location of the first column of the font
  fontidx = _charoffset[charnum]-1;

  // get the width of the font
  colct = pgm_read_byte_near(_charwidth + charnum);
  for (byte i=colct; i>0; i--) {
    colbits = pgm_read_byte_near(_font + fontidx + i);
    for (byte j=0; j<=7; j++) {
      if ((colbits >>j) & 1) {
        SetLed(x, y-j, 1);
      }
    }
    x++;
  }
  return colct+1;
}
// ------------------------------------------------------------------------------------
// Sets the Text for Scrolline
void AS1107::SetScrollText(char *string, int charspacing)
{
  _charspacing = charspacing;
  _outputstring = string;
  _curchr = string;
  _hastext = true;
  _colct =-1;
}

// ------------------------------------------------------------------------------------
// Scrolls the text one pixel to the left
// returns true if last character has been displayed
boolean AS1107::TextScroll()
{
  boolean lastchar = false;
  byte colbits = 0;
    if (_colct == (0-_charspacing-1)) {
      lastchar = NextCharacter();
    }
    if (_colct>=0) {
      colbits = pgm_read_byte_near(_font + _fontidx + _colct);
    }
    ShiftLeft();
    _buffer[Maxx] = colbits;
    Update();
    _colct--;
  return lastchar;
}

// ------------------------------------------------------------------------------------
// PRIVATE (Internal) functions
// ------------------------------------------------------------------------------------
// Set LED without Parameter check
void AS1107::SetLedInternal(byte x, byte y, byte value)
{
  _buffer[x] |= (value << (Maxy-y));
}
// Set LED without Parameter check
void AS1107::SetLedInternalD(byte x, byte y, byte value)
{
  _buffer[x] = (value << (Maxy-y));
}

// ------------------------------------------------------------------------------------
// fetches the next character of the Scrollline
// returns true if string is at the end
boolean AS1107::NextCharacter()
{
  boolean lastchar = false;
  if (_hastext) {
    char thechar = *_curchr;
    boolean found = false;
    byte charnum = 0;
    byte i;
    // if the string ends, start from the beginning
    if (thechar == 0) {
      lastchar = true;
      _curchr = _outputstring;
      thechar = *_curchr;
    }

    charnum = GetInternalCharCode(thechar);

    // get the offset of the first column of the character
    _fontidx = _charoffset[charnum];

    // get the width of the font
    _colct = pgm_read_byte_near(_charwidth + charnum) -1;
  }
  else {
    _fontidx= _charoffset[_repcharoff];
    _colct = pgm_read_byte_near(_charwidth + _repcharoff);
  }
  *_curchr++;
  return lastchar;
}
// ------------------------------------------------------------------------------------
// calculates Character offsets from font width table in EEPROM
void AS1107::CalculateCharOffsets()
{
  int off =0;
  int idx=0;
  int w=0;
  int i=0;

  do {
    _charoffset[i]=off;
    w = pgm_read_byte_near(_charwidth+i);
    off += w;
    i++;
  } while (w != 0);
}

// ------------------------------------------------------------------------------------
// gets the character number of the built-in-font from the ASCII table
// returns number of the replacement character for unknown characters
byte AS1107::GetInternalCharCode(byte thechar)
{
    int i=0;
    int charnum;
    do {
      charnum = pgm_read_byte_near(_charcodes + i);
      if (charnum == thechar) break;
      i++;
    } while (charnum != 0 );
    if (charnum == 0) i = _repcharoff;
    return i;
}

Il s'agit de la librairie de Stephan Elsner que j'ai remanié pour mes besoins.

AS1107.h

/*
  AS1107.h
*/

#ifndef AS1107_h
#define AS1107_h

#include "Arduino.h"
#include <avr/pgmspace.h>

#define ON 1
#define OFF 0


// --------------------------------------------------------------------------------------------------------------------------
class AS1107
{
  public:
    AS1107(byte cspin, byte clkpin, byte datapin);
    void WriteRegister2(byte chip, byte reg, byte data);
    void WriteRegister(byte chip, byte reg, byte data);
    void WriteColumn( byte column, byte data);
    void Init(byte *buffer);
    void SetBuffer(byte *buffer);
    void SetLed(int x, int y, byte value);
    void SetLedD(int x, int y, byte value);
    void Clear();
    void Update();
    void ShiftLeft();
    void ShiftRight();
    void ShiftUp();
    void ShiftDown();
    void ShiftUp(byte from, byte to);
    void ShiftDown(byte from, byte to);
    void DrawLine(int x0, int y0, int x1, int y1);
    void EraseLine(int x0, int y0, int x1, int y1);
    void DrawBox(int x0, int y0, int x1, int y1);
    void DrawEllipse(int xm, int ym, int a, int b);
    void SetScrollText(char *string, int charspacing);
    void DrawText (int x, int y, char *str);
    byte DrawChar (int x, int y, char thechar);

    boolean TextScroll();

    // ***************************************
    // Set your module configuration here
    // ***************************************
    static const byte NbMod=5;
    static const byte Maxx=(8*NbMod)-1;      // maximum x - Pixels of the Module
    static const byte Maxy=7;         // maximum y - Pixels of the Module
    static const byte HighestCtrlNum=NbMod-1; // Number of Matrix modules -1 (0 = single module)

  private:
    byte _cspin;
    byte _clkpin;
    byte _datapin;
    byte *_buffer;                    // pointer to current screen buffer

    static const byte _repcharoff;    // Offset of the replacement for unknown characers
    int  _charoffset[87];             // Start position in Array
    char *_outputstring;              // pointer to start of output string
    char *_curchr;                    // pointer to current char of output String
    int _fontidx;                     // current byte in font to display
    int _colct;                       // to count the columns of character to display
    byte _charspacing;                // the coulumns of space between characters
    boolean _hastext;

    void SetLedInternal(byte x, byte y, byte value);
    void SetLedInternalD(byte x, byte y, byte value);
    boolean NextCharacter();
    void CalculateCharOffsets();
    byte GetInternalCharCode(byte thechar);
};

// --------------------------------------------------------------------------------------------------------------------------
// AS1107-Register
class Registers
{
  public:
    static const byte NoOp   = 0x00;
    static const byte Digit0 = 0x01;
    static const byte Digit1 = 0x02;
    static const byte Digit2 = 0x03;
    static const byte Digit3 = 0x04;
    static const byte Digit4 = 0x05;
    static const byte Digit5 = 0x06;
    static const byte Digit6 = 0x07;
    static const byte Digit7 = 0x08;
    static const byte DecodeMode = 0x09;
    static const byte IntensityControl = 0x0A;
    static const byte ScanLimit = 0x0B;
    static const byte Shutdown = 0x0C;
    static const byte Feature = 0x0E;
    static const byte DisplayTest = 0x0F;
};

// --------------------------------------------------------------------------------------------------------------------------
// Values to write to the Shutdown Register
class ShutdownModes
{
  public:
    static const byte ShutdownResetFeature = 0x00;  // Shutdown Mode, Reset Feature Register to Default Settings
    static const byte Shutdown             = 0x80;  // Shutdown Mode, leaving Feature Register unchanged
    static const byte NormalResetFeature   = 0x01;  // Normal Mode, Reset Feature
    static const byte Normal               = 0x81;  // Normal Mode, Feature unchanged
};

// Bits in the feature-Register, desired Settings must be OR'ed together
class Features
{
  public:
    static const byte ExternalClock        = 0x01;  // ExternalClock active
    static const byte ResetRegisters       = 0x02;  // Resets all control registers except the Feature Register.
    static const byte HexDecoding          = 0x04;  // 1 = Enable HEX decoding, 0 = Enable Code-B decoding
    static const byte SPIEnable            = 0x08;  // Enables the SPI-compatible interface.(AS1106 only).
    static const byte BlinkEnable          = 0x10;  // Enables blinking.
    static const byte BlinkSlow            = 0x20;  // Sets blink with low frequency
                                                    // (with the internal oscillator enabled)

    static const byte BlinkSync            = 0x40;  // Synchronizes blinking on the rising edge of pin LOAD/CSN.
                                                    // The multiplex and blink timing counter is cleared on the
                                                    // rising edge of pin LOAD/CSN. By setting this bit in
                                                    // multiple AS1106/AS1107 devices, the blink timing can
                                                    // be synchronized across all the devices.

    static const byte BlinkStartWithOn     = 0x80;  // Start Blinking with display enabled phase.
                                                    // When bit D4 (blink_en) is set, bit D7
                                                    // determines how blinking starts.
                                                    // 0 = Blinking starts with the display turned off.
                                                    // 1 = Blinking starts with the display turned on.
};

#endif


Avec mon code je dois dépasser la capacité de l'éditeur, la suite dans le message suivant.

tilowil

La suite...
et enfin le programme servant pour l'affichage
CTB.ino

#include <AS1107.h>

// Arduino pins
const byte CsnPin = 10;    // Chip select
const byte ClkPin = 11;    // Serial Clock
const byte DataPin = 12;   // Serial Data

byte buffer[40];          // Screen buffer (Nb. de modules * 8)
AS1107 matrix(CsnPin, ClkPin, DataPin);

const byte d = 0;
int count=1;
void setup()
{
  //Serial.begin(9600);
  matrix.Init(buffer);
  matrix.SetScrollText("% Halloween Party 2014.  &    ", 1);
}

void loop()
{
   // Animations programmées (20)
   // - Scroll "[Mickey] Halloween Party 2014. [Skull]"
   // - Pulsation de cercles (CirclePulsate())
   // - Chute d'étoiles (StarsDown())
   // - Ligne tournante (Rotator1())
   // - Champ d'étoiles (StarsRight())
   // - Lignes (Lines())
   // - Balle rebondissante (bounce())
   // - Oeil avec clignement (EyeBlink())
   // - Pulsation cardiaque (HeartPulsing())
   // - Coeurs (plein/vide) (Hearts())
   // - Gros "OK" (BigOk())
   // - Viseur Cyclope (Cyclope())
   // - Cylon (oeil 4 leds) (Cylon())
   // - Cylon2 (oeil 16 leds) (Cylon2())
   // - Lignes verticales scrollent vers la gauche (VertiLines("L"))
   // - Lignes verticales scrollent vers la droite (VertiLines("R"))
   // - Remplissage vers la droite et retour (FillingLine("R"))
   // - Remplissage vers la gauche et retour (FillingLine("L"))
   // - Faux vu-metre sur 5 colonnes (sep : 1 led) (Egaliser())
   // - Remplissage bloc (FillingBlock())
   
   if (matrix.TextScroll())
   {
     delay(2000);
     for (int i=0; i<=7; i++)
     {
       matrix.ShiftUp();
       delay(50);
       matrix.Update();
     }
 
   matrix.Clear();
   matrix.DrawText(0,0,"EyeBlink");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   EyeBlink(); // V

   matrix.Clear();
   matrix.DrawText(0,0,"HP");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   HeartPulsing(); // V

   matrix.Clear();
   matrix.DrawText(0,0,"Lines");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   Lines(); // V

   matrix.Clear();
   matrix.DrawText(0,0,"Hearts");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   Hearts(); // V

   matrix.Clear();
   matrix.DrawText(0,0,"BOK");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   BigOk(); // V

   matrix.Clear();
   matrix.DrawText(0,0,"Cyclops");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   Cyclope(); // V

   matrix.Clear();
   matrix.DrawText(0,0,"Cylon");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   Cylon(); // V

   matrix.Clear();
   matrix.DrawText(0,0,"Cylon2");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   Cylon2(); // V

   matrix.Clear();
   matrix.DrawText(0,0,"VertiL");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   VertiLines("L"); // V

   matrix.Clear();
   matrix.DrawText(0,0,"VertiR");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   VertiLines("R"); // V

   matrix.Clear();
   matrix.DrawText(0,0,"FillL");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   FillingLine("L"); // V

   matrix.Clear();
   matrix.DrawText(0,0,"FillR");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   FillingLine("R"); // \ depilement à revoir.

   matrix.Clear();
   matrix.DrawText(0,0,"EQ");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   Egaliser(); // V
   
   matrix.Clear();
   matrix.DrawText(0,0,"FB");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   FillingBlock(); //

   matrix.Clear();
   matrix.DrawText(0,0,"Circle");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   
   // \WRO   
   for (int i=0; i<=10; i++)
   {
     CirclePulsate();
   }
   matrix.Clear();
   matrix.DrawText(0,0,"SD");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   
   StarsDown();
   matrix.Clear();
   matrix.DrawText(0,0,"Rotate");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   
   for (int i=0; i<=5; i++)
   {
     Rotator1();
   }
   matrix.Clear();
   matrix.DrawText(0,0,"SR");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   
   StarsRight();
   
   for (int i=0; i<=AS1107::Maxx; i++)
   {
     matrix.ShiftRight();
     delay(5);
     matrix.Update();
   }
   matrix.Clear();
   matrix.DrawText(0,0,"bounce");
   matrix.Update();
   delay(2000);
   matrix.Clear();
   
   for (int i=1; i<=3; i++)
   {
     bounce();
//  }}}}
}
}
   delay(10);
}

void FillingBlock()
{
  int dx=0;
  int fx=AS1107::Maxx-4;

  for (int i=0;i<=AS1107::Maxx/4;i++)
  {
   // Descente du bloc
   for (int j=0;j<=7;j++)
   {
    matrix.DrawLine(dx,j,dx,j+4);
    matrix.Update();
    delay(d);
   }
   if (fx!=dx)
   {
     // on pousse le bloc pour l'empiler
     for (int j=dx+1;j<=fx-4;j++)
     {
       matrix.DrawLine(j+4,0,j+4,7);
       matrix.EraseLine(j-1,0,j-1,7);
       matrix.Update();
       delay(d);
     }
     fx=fx-4;
   }
     
  } 
}

void DrawEgaliser(int colx[], int larg[], int coly[], int oldy[])
{
int realy[]={7,6,5,4,3,2,1,0};
matrix.Clear();
for (int i=0;i<=6;i++)
{
     for (int j=realy[0];j>=realy[coly[i]];j--)
     {
       matrix.DrawLine(colx[i],j,colx[i]+larg[i],j);
     } 
}
matrix.Update();


void Egaliser()
{
// definition des positions des colonnes
int colx[]= {0,4,10,16,22,28,34};
// definition des largeurs des colonnes
int larg[]= {2,4,4,4,4,4,4};
// definition des hauteurs des colonnes
int coly[]= {7,7,7,7,7,7,7};
// définition des variable de sauvegardes
int oldy[]={0,0,0,0,0,0,0};

matrix.Clear();
matrix.Update();
// dessin de la base de l'egaliseur
for (int j=0;j<=100;j++)
{
  //définition des nouvelles hauteurs
  for (int i=0;i<=6;i++)
  {
   coly[i]=random(0,8);
  }
  DrawEgaliser(colx,larg,coly,oldy);
  delay(100);
  for (int i=0;i<=6;i++)
  {
   oldy[i]=coly[i];
  }     
}


void FillingLine(char* sens)
{
  int dx=0;
  int fx=AS1107::Maxx;
  matrix.Clear();
  matrix.Update();
  if (sens=="R")
  {
   for (int i=0;i<=AS1107::Maxx;i++)
   {
     // dessin de la ligne a pousser
     matrix.DrawLine(dx,0,dx,7);
     matrix.Update();
     // on pousse la ligne pour l'empiler
     for (int j=1;j<=fx;j++)
     {
       matrix.DrawLine(j,0,j,7);
       matrix.EraseLine(j-1,0,j-1,7);
       matrix.Update();
       delay(d);
     }
     fx--; 
   }
   delay(1000);
   // on depile
   for (int i=0;i<=AS1107::Maxx;i++)
   {
     // on pousse la ligne pour la dépiler
     for (int j=fx;j>=0;j--)
     {
       matrix.DrawLine(j-1,0,j-1,7);
       matrix.EraseLine(j,0,j,7);
       matrix.Update();
       delay(d);
     }
     fx++; 
   }
}
else if (sens=="L")
{
   for (int i=0;i<=AS1107::Maxx;i++)
   {
     // dessin de la ligne a pousser
     matrix.DrawLine(fx,0,fx,7);
     matrix.Update();
     // on pousse la ligne pour l'empiler
     for (int j=fx;j>=dx;j--)
     {
       matrix.DrawLine(j,0,j,7);
       matrix.EraseLine(j+1,0,j+1,7);
       matrix.Update();
       delay(d);
     }
     dx++; 
   }
   delay(1000);
   // on depile
   for (int i=0;i<=AS1107::Maxx;i++)
   {
     // on pousse la ligne pour la dépiler
     for (int j=dx;j<=fx;j++)
     {
       matrix.DrawLine(j+1,0,j+1,7);
       matrix.EraseLine(j,0,j,7);
       matrix.Update();
       delay(d);
     }
     dx--; 
   }



void VertiLines(char* sens)
{
  int x=0;
  matrix.Clear();
  matrix.Update();
  if (sens == "L")
  {
   x=AS1107::Maxx;
  } 
  for (int j=0;j<=100;j++)
  {
    if ((j%8)==0)
    {
      matrix.DrawLine(x,0,x,7);
    }
    else
    {
      if (sens=="L")
      {
        matrix.ShiftLeft();
      }
      else
      {
        matrix.ShiftRight();
      }
    }
    matrix.Update();
    delay(d);
  }


void Cylon()
{
  matrix.Clear();
  matrix.Update();
  // Initialisation du carré (oeil)
  matrix.DrawBox(0,3,1,4);
  matrix.Update();
  // Lancement du scroll
  for (int j=1;j<=5;j++)
  {
    for (int i=0;i<=(AS1107::Maxx-2);i++)
    {
       matrix.ShiftRight();
       delay(5);
       matrix.Update();
    } 
    for (int i=0;i<=(AS1107::Maxx-2);i++)
    {
       matrix.ShiftLeft();
       delay(5);
       matrix.Update();
    } 
  } 

void Cylon2()
{
  matrix.Clear();
  matrix.Update();
  // Initialisation du carré (oeil)
  matrix.DrawBox(1,3,2,4);
  matrix.DrawBox(0,2,3,5);
  matrix.Update();
  // Lancement du scroll
  for (int j=1;j<=5;j++)
  {
    for (int i=0;i<=(AS1107::Maxx-4);i++)
    {
       matrix.ShiftRight();
       delay(5);
       matrix.Update();
    } 
    for (int i=0;i<=(AS1107::Maxx-4);i++)
    {
       matrix.ShiftLeft();
       delay(5);
       matrix.Update();
    } 
  } 


void Cyclope()
{
  int lx = 0;
  int ly = 0;
  int rx = AS1107::Maxx;
  int ry = AS1107::Maxy;
 
  matrix.Clear();
  matrix.Update();
  for (int j=1;j<=4;j++)
  {
    matrix.DrawBox(rx,ry,lx,ly);
    matrix.Update();
    delay(1000);
    lx++;
    rx--;
    for (int i=1;i<=4;i++)
    {
      matrix.DrawBox(rx,ry,lx,ly);
      lx++;
      rx--;
      matrix.Update();
    }
    ly++;
    ry--;
  }
}

void BigOk()
{
  int o = 17;
  int k = 22;
  matrix.Clear();
  for (int i=1; i<=9; i++)
  {
    if (i < 4)
    {
      matrix.DrawLine(o,0,o,7);
      matrix.DrawLine(k,0,k,7);
    }
    if (i > 3 and i < 7)
    {
      matrix.SetLed(o,0,ON);
      matrix.SetLed(o,7,ON);
      matrix.DrawLine(k,3-(i-4),k,4+(i-4));
    }
    if (i>6)
    {
      matrix.DrawLine(o,0,o,7);
      // Spécificité K
      if (i==7) matrix.DrawLine(k,0,k,7);
      if (i==8)
      {
        matrix.DrawLine(k,0,k,2);
        matrix.DrawLine(k,5,k,7);
      }
      if (i==9)
      {
        matrix.DrawLine(k,0,k,1);
        matrix.DrawLine(k,6,k,7);
      }
    }
    matrix.Update();
    o--;
    k++;
    delay(d);
  }
  delay(3000);
  for (int i=0; i<=5; i++)
  {
    matrix.Clear();
    matrix.Update();
    delay(500);
    // Ecriture du gros OK
    // O
    matrix.DrawBox(9,0,17,7);
    matrix.DrawBox(10,0,16,7);
    matrix.DrawBox(11,0,15,7);
    // K
    matrix.DrawLine(22,0,22,7);
    matrix.DrawLine(23,0,23,7);
    matrix.DrawLine(24,0,24,7);
    matrix.DrawLine(25,3,28,0);
    matrix.DrawLine(25,4,28,7);
    matrix.DrawLine(26,3,29,0);
    matrix.DrawLine(26,4,29,7);
    matrix.DrawLine(27,3,30,0);
    matrix.DrawLine(27,4,30,7);
    matrix.DrawLine(28,3,30,1);
    matrix.DrawLine(28,4,30,6);
    //
    matrix.Update();
    delay(500);
  }
  // Fermeture du OK
  for (int i=9; i>=0; i--)
  {
    if (i < 4)
    {
      matrix.EraseLine(o,0,o,7);
      matrix.EraseLine(k,0,k,7);
    }
    if (i > 3 and i < 7)
    {
      matrix.SetLedD(o,0,OFF);
      matrix.SetLedD(o,7,OFF);
      matrix.EraseLine(k,3-(i-4),k,4+(i-4));
    }
    if (i>6)
    {
      matrix.EraseLine(o,0,o,7);
      // Spécificité K
      if (i==7) matrix.EraseLine(k,0,k,7);
      if (i==8)
      {
        matrix.EraseLine(k,0,k,2);
        matrix.EraseLine(k,5,k,7);
      }
      if (i==9)
      {
        matrix.EraseLine(k,0,k,1);
        matrix.EraseLine(k,6,k,7);
      }
    }
    matrix.Update();
    o++;
    k--;
    delay(d);
  }


void Hearts()
{
  for (int i=0; i<=5; i++)
  {
    matrix.Clear();
    matrix.DrawText(4,0,"# # #");
    matrix.Update();
    delay(2000);
    matrix.Clear();
    matrix.DrawText(4,0,"$ $ $");
    matrix.Update();
    delay(2000);
  }


void HeartPulsing()
{
  // Allumage du Heart Pulse
  for( int i=0; i <= AS1107::Maxx; i++)
  {
    if (i < 14 or i > 24)
    {
      matrix.SetLed(i,3,ON);
    }
    if (i > 13 and i < 17)
    {
      matrix.SetLed(i,16-i,ON);
    } 
    if (i > 16 and i < 23)
    {
      matrix.SetLed(i,i-16,ON);
    } 
    if (i > 22 and i < 25)
    {
      matrix.SetLed(i,28-i,ON);
    } 
    matrix.Update();
    delay(d);
  }
  // Extinction du Heart Pulse
  for( int i=0; i <= AS1107::Maxx; i++)
  {
    if (i < 14 or i > 24)
    {
      matrix.SetLedD(i,3,OFF);
    }
    if (i > 13 and i < 17)
    {
      matrix.SetLedD(i,16-i,OFF);
    } 
    if (i > 16 and i < 23)
    {
      matrix.SetLedD(i,i-16,OFF);
    } 
    if (i > 22 and i < 25)
    {
      matrix.SetLedD(i,28-i,OFF);
    } 
    matrix.Update();
    delay(d);
  }
}

void EyeHeart()
{
  matrix.Clear();
  matrix.DrawText(8,0,"%");
  matrix.DrawText(24,0,"%");
  matrix.Update();
  delay(2000);
}

void Lines()
{
  for (int j=1; j<=5; j++)
  {
    for (int i=0; i<=3; i++)
    {
      matrix.Clear();
      matrix.DrawLine(0,0+i,AS1107::Maxx,0+i);
      matrix.DrawLine(0,AS1107::Maxy-i,AS1107::Maxx,AS1107::Maxy-i);
      matrix.Update();
      delay(500);
    }
    for (int i=3; i>=0; i--)
    {
      matrix.Clear();
      matrix.DrawLine(0,0+i,AS1107::Maxx,0+i);
      matrix.DrawLine(0,AS1107::Maxy-i,AS1107::Maxx,AS1107::Maxy-i);
      matrix.Update();
      delay(500);
    }
  }
}

void EyeBlink()
{
for (int i=0; i<=5; i++)
{
   matrix.Clear();
   // dessin des yeux
   matrix.DrawText(4,0,"]  ]");
   matrix.Update();
   delay(5000);
   matrix.Clear();
   matrix.DrawText(4,0,"[  [");
   matrix.Update();
   delay(500);
}
}
 
void CirclePulsate()
{
   for( int i=0; i<=15; i++)
   {
     matrix.Clear();
     matrix.DrawEllipse(AS1107::Maxx/2,4,i,i);
     matrix.Update();
     delay(d);
   }
}

void StarsDown()
{
     for( int i=0; i<=200; i++)
     {
       matrix.ShiftDown();
       matrix.SetLed((byte) random(0,AS1107::Maxx+1),0,1);
       matrix.SetLed((byte) random(0,AS1107::Maxx+1),0,1);
       matrix.SetLed((byte) random(0,AS1107::Maxx+1),0,1);
       matrix.SetLed((byte) random(0,AS1107::Maxx+1),0,1);
       matrix.SetLed((byte) random(0,AS1107::Maxx+1),0,1);
       matrix.Update();
       delay(d);
     }
}

void StarsRight()
{
     for( int i=0; i<=200; i++)
     {
       matrix.ShiftRight();
       matrix.SetLed(0,(byte) random(0,AS1107::Maxy+1),1);
       matrix.Update();
       delay(d);
     }
}

void Rotator1()
{
   for( int i=0; i<=AS1107::Maxx-1; i++)
   {
     matrix.Clear();
     matrix.DrawLine(i,0,AS1107::Maxx-i,AS1107::Maxy);
     matrix.Update();
     delay(d);
   }
   for( int i=0; i<=6; i++)
   {
     matrix.Clear();
     matrix.DrawLine(AS1107::Maxx,i,0,7-i);
     matrix.Update();
     delay(d);
   }
}

void bounce()
{
   int rad=0;
   float y=random(0,AS1107::Maxy+1);
   float x=random(0,AS1107::Maxx+1);
   float xacc=random(0,5)-2;
   float yacc=random(0,5)-2;
   float yg=0.08;
   if (xacc == 0) xacc = 1;
   if (yacc == 0) yacc = -1;
   
   for (int i=1; i<=300; i++)
   {
     x+=xacc;
     y+=yacc;
     yacc += yg;
     if (x >= (AS1107::Maxx-rad))
     {
       xacc = -xacc*0.9;
       x= AS1107::Maxx -rad;
     }
     else if (x <= rad)
     {
       xacc = -xacc*0.8;
       x= rad;
     }
     if (y >= (AS1107::Maxy-rad))
     {
       yacc = -(yacc*0.80);
       y= AS1107::Maxy -rad;
     }
     else if (y <= rad)
     {
       yacc = -yacc*0.8;
       y= rad;
     }
     matrix.Clear();
     matrix.SetLed(x,y,1);
     matrix.Update();
   }
}


Il me reste encore un peu de travail sr le code, entre autres augmenter sa vitesse (si vous avez des idées je suis preneur), programmer l'animation des oreilles et du coté de la visière (piloté par 1 seul AS1107). Il faut aussi que je programme les boutons (séquentiel, précédent, suivant).
Mon fils m'ayant demander un second scroll je me suis rendu compte d'un bug. Actuellement je ne peux mettre qu'un seul scroll. Un bug a corriger  :D.
Une fois tous ces éléments de programmations finis et verrouillé par des tests sur breadboard, je poursuivrais le reste du déguisement.

Merci pour vos messages, votre aide.
@ petit lapin : "Alors heureux ?"  :D :D :D
@ spectroman : Tu te rends compte que tous ça c'est grâce à toi :)

spectroman



const byte CsnPin = 10;    // Chip select
const byte ClkPin = 11;    // Serial Clock
const byte DataPin = 12;   // Serial Data

byte buffer[40];          // Screen buffer (Nb. de modules * 8)
AS1107 matrix(CsnPin, ClkPin, DataPin);

j'ai jamais fait de c++, mais je suis un gros radin avec la RAM.

const mets les données en zone Read only. Mais comme sur un atmega le cpu ne peut pas lire des données en flash (sauf avec des fonctions spéciales), const ne sert presque à rien, ça reste des données en RAM.

tu peux pas faire un define pour CsnPin....?


void Egaliser()
{
// definition des positions des colonnes
int colx[]= {0,4,10,16,22,28,34};
// definition des largeurs des colonnes
int larg[]= {2,4,4,4,4,4,4};
// definition des hauteurs des colonnes
int coly[]= {7,7,7,7,7,7,7};
// définition des variable de sauvegardes
int oldy[]={0,0,0,0,0,0,0};


64 octets sur la pile, assassin. >:D

Citation
Merci pour vos messages, votre aide.
@ petit lapin : "Alors heureux ?"  :D :D :D
@ spectroman : Tu te rends compte que tous ça c'est grâce à toi :)
non c'est toi qui a fait tout le boulot :D

tilowil

Je n'ai pas tout compris dans tes remarques, désolé. :(

Citation de: spectroman le Samedi 05 Avril 2014, 19:21:23 PM

const byte CsnPin = 10;    // Chip select
const byte ClkPin = 11;    // Serial Clock
const byte DataPin = 12;   // Serial Data

byte buffer[40];          // Screen buffer (Nb. de modules * 8)
AS1107 matrix(CsnPin, ClkPin, DataPin);

j'ai jamais fait de c++, mais je suis un gros radin avec la RAM.

const mets les données en zone Read only. Mais comme sur un atmega le cpu ne peut pas lire des données en flash (sauf avec des fonctions spéciales), const ne sert presque à rien, ça reste des données en RAM.

tu peux pas faire un define pour CsnPin....?
CsnPin, ClkPin et DataPin, sont des constantes qui ne doivent pas bouger durant l'execution du programme, car elles correspondent aux pin de sortie de l'Arduino, CsnPin (pin du Chip Select), ClkPin (pin du Clock) et DataPin(pin du Data in). Mon arduino a un ATmega2580 (Arduino Mega2560)

Citation de: spectroman le Samedi 05 Avril 2014, 19:21:23 PM

void Egaliser()
{
// definition des positions des colonnes
int colx[]= {0,4,10,16,22,28,34};
// definition des largeurs des colonnes
int larg[]= {2,4,4,4,4,4,4};
// definition des hauteurs des colonnes
int coly[]= {7,7,7,7,7,7,7};
// définition des variable de sauvegardes
int oldy[]={0,0,0,0,0,0,0};


64 octets sur la pile, assassin. >:D
Quelle pile ? je défini un tableau qui contient chaque colonne du vu-mètre. Je peux virer oldy[] dont je ne me sert plus.

Citation de: spectroman le Samedi 05 Avril 2014, 19:21:23 PM
non c'est toi qui a fait tout le boulot :D
Enfin c'est toi qui m'a expliqué pour que l'affichage fonctionne sur les 5 matrices, et d'ailleurs maintenant que je suis passé sur les AS1107, je n'ai plus besoin des condensateurs.

Pour le moment avec mon programme je n'utilise que 5% de mon arduino.

Little_Rabbit

Salut,

Citation de: tilowil le Samedi 05 Avril 2014, 14:00:58 PM
@ petit lapin : "Alors heureux ?"  :D :D :D

Ravi !  :D

Bravo pour tes corrections !  ^-

L'équalizeur est top là ! Pour le mode Cylon, tu as raison, dans l'original "l'œil" est finalement tout petit. Sans doute avais-je en tête les robots de Berzerk ;). Mais c'est sympa comme ça aussi non ? :)

Pour tes problèmes de vitesse, effectivement avec 3 modules c'est parfait ! Ne connaissant absolument pas les AS1107 (ni l'Arduino en fait  :-\), je ne suis pas sûr d'avoir compris la cause du ralentissement... tu envoies en série la trame de chaque module, et la vitesse de cette communication série est telle que si tu dépasses 3 modules, il n'est plus possible d'avoir un taux de rafraîchissement suffisant ? Si tel est le cas, resterait-il d'autres broches sur l'arduino pour adresser en parallèle 2 blocs AS1107 (un bloc de 3 + un bloc de 2). Ainsi tu doublerais ta bande passante pour la communication avec les AS1107... Je dis ça sans avoir du tout analyser le code, et je ne sais pas notamment si c'est toi qui gère la matrice de points de chaque module, ou si l'AS1107 possède des commandes "intelligentes" de scroll dans différentes directions...

Quant aux remarques de Spectorman, je pense qu'il veut dire que la nature de tes variables ou constantes affecte le type de mémoire utilisée dans l'Arduino, et par conséquence pourrait en affecter la vitesse d'exécution. En C, un #define est véritablement une constante dont la valeur est substituée au niveau du préprocesseur C, et qui dans le code généré se traduira par une constante dont la valeur sera directement l'opérande de ton instruction assembleur (ex LDA #65 en 6502 ;) ). Une constante au sens C, de type "const byte CsnPin = 10;" n'a de constante que le fait que sa valeur ne changera jamais durant l'exécution de ton code, mais cela reste une valeur stockée dans une case mémoire exactement comme celle d'une variable. En assembleur cela se traduira potentiellement par une instruction qui ira chercher cette valeur en mémoire, puis la traitera selon l'instruction dans laquelle elle est utilisée :). En gros cela fait potentiellement un accès mémoire en plus pour rien ;).

Donc un "#define CsnPin 10" te générera probablement un code plus efficace qu'un "const byte CsnPin = 10;" ;). Spectroman confirmera (ou pas) ce que j'essaye d'expliquer :).

Quant à la pile, peut-être parle-t-il de variables locales qui sont souvent allouées dynamiquement dans le pile du microprocesseur. Je ne connais pas la taille de la pile de l'Arduino. Vue la remarque de Spectroman, j'en déduirais qu'il est peut-être luxueux d'allouer un tableau de cette taille dans la pile... Il nous apportera sûrement des précisions. :D

Bravo en tous cas pour tes avancées !  ^-

Note bien que mes remarques ne sont que le reflet de mon ressenti... Non, mes désires ne sont pas des ordres  :D.

A++
Recherche bornes dédiées ou PCB originaux: Miss Pacman, Dig Dug, Galaga, Mappy, Asteroids, Battlezone, Missile Command, Tempest, Star Wars, Donkey Kong (+ Jr), Mario Bros, Moon Patrol, Defender, Joust, Frogger, Gyruss, Pooyan, Space Tactics, Zaxxon, etc. Flip : Gottlieb des années 80 (Spirit, Amazon Hunt, ...), Baby Pac Man. Divers :  Ice Cold Beer => Trois fois rien quoi ! :D
Ma séance sur le divan : c'est grave Docteur ? :-\
Ma gaming room, ma storage room

spectroman

#24
D'abords bravo tilowil.

Oui little_rabbit, c'est que je voulais dire mais on a écrit la réponse au même moment. <:)

Citation de: tilowil le Samedi 05 Avril 2014, 20:15:22 PM
CsnPin, ClkPin et DataPin, sont des constantes qui ne doivent pas bouger durant l'execution du programme, car elles correspondent aux pin de sortie de l'Arduino, CsnPin (pin du Chip Select), ClkPin (pin du Clock) et DataPin(pin du Data in). Mon arduino a un ATmega2580 (Arduino Mega2560)
ca dois marcher si tu fais :


#define CsnPin 10    // Chip select
#define ClkPin 11    // Serial Clock
#define DataPin 12   // Serial Data


Citation de: tilowil le Samedi 05 Avril 2014, 20:15:22 PM
Quelle pile ? je défini un tableau qui contient chaque colonne du vu-mètre. Je peux virer oldy[] dont je ne me sert plus.

La mémoire se sépare en deux parties :
- une pour les variables globale
- une pour la pile et le tas (stack et heap)

exemple pour un cpu de 16K de RAM:

0x0000...0x0102 : variables globales, statiques
0x0103 => début du TAS
.....
0x3fff => début de la pile (chaque élément mis fait décroitre la pile)

Les allocations statiques, variables globales et statiques se font dans la première partie.
Les allocations dynamiques malloc, new se font sur le tas.
Les allocation des variables locales et des paramètres (si on dépasse le nombre de registres dédiés) se font sur la pile.

Le problème quand tu alloue beaucoup d'octet (c'est relatif) sur la pile, c'est que tu risque des problèmes à l'exécution.

Du genre quand je rajoute ce bout de code ça marche plus, quand je l'enlève ça remarche. Ou si j'enlève l'optimisation pour déboger plus facilement, ça marche plus. Du coup tu perds des
heures avant comprendre que le problème c'est pas le bout de code ou le compilateur, mais un problème de pile.

Quand tu dois allouer pas mal de donnés sur des petits micros, favorise les allocations statiques et dynamiques (en début de programme si possible, et sans free et delete).

Bon après je chipote, ton programme marche c'est la le but, donc je :fleche:




tilowil

Merci pour vos remarques à tous les 2. C'est une mauvaise habitude que j'ai prise en suivant les exemples fourni avec l'éditeur de programmation. Demain je ferais l'essai. Par contre ce qui est assez drôle, et je pense que je vais changer l'orientation de mes matrices, c'est qu'en utilisant la fonction setRow l'affichage se produit plus rapidement qu'avec la fonction setColumn. Ces deux fonction sont dérivées de ledControl (pour Max7221).

Pour répondre à ta question concernant l'affichage, je défini un buffer correspondant au nombre de colonne qu'il y a dans l'afficheur (40 dans mon cas), ensuite je transmet ce buffer directement aux AS1107 ou au Max7221 par le data in. Sachant que chaque AS1107 (ou Max 7221/7219) on une sortie data out que l'on doit relié à entrée data in du boitier suivant et ainsi de suite jusqu'au dernier boitier. le CS (Chip selector) lui est monté en sorte que chaque patte CS de chaque boitier soit connectée ensemble et à une sortie de l'Arduino. A chaque fois le buffer est affiché entièrement. C'est pour ça que dans ma vidéo  à 3 modules je cache les 2 derniers modules, car ils reproduisaient l'affichage des 2 premiers modules. En fait plus il y a de modules plus le buffer est grand et plus c'est lent. Il y a un maximum de 8 matrices par groupe. Après j'ai fait des essais non concluant pour ajouter les jeu de lumière des oreilles et des cotés. Je pense que je vais devoir revoir le programme pour faire une pseudo gestion d'interruptions afin de de pouvoir exécuter 3 programmes en même temps (visière, cotés et oreilles). Je ne suis pas près de commencer les perçages.

@Little_Rabbit : je n'ai pas pris ta remarque pour un ordre ;) je voulais juste voir ce que ça faisait, et le montrer à mon fils, c'est lui qui va porter.

je vous referai un petit topo demain soir.

tilowil

Donc j'ai un peu avancé, pas beaucoup.

en ajoutant les #defines et en modifiant l'utilisation du tableau pour l'égaliseur


je n'ai pas vu de changement

J'ai commencer à travailler sur une autre version qui me permet de faire une pseudo gestion d'interruption et de lancer plusieurs tache en même temps. La mise en évidence de la différence entre l'instruction setRow et setColumn

Avec l'instruction setRow (il faut que j'oriente mes matrices différemment)


Avec l'instruction setRow (ne regardez pas le sens de défilement, je n'ai pas modifié le code, juste remplacé le setRow par setColumn)


Si je garde cette méthode, qui me permet de gérer en même temps l'affichage de la visière, du coté de la visière et des oreilles, sinon je serai obligé d'avoir un Arduino pour la visière et un Arduino pour les jeux de lumière des oreilles et des cotés de la visière.

Donc il faut que je revois ma programmation pour y intégrer tous les principes que j'avais mis en place dans ma v1. Cette nouvelle façon de faire me permet d'utiliser plusieurs scrolling (contrairement à la v1).
Je pense que la reprogrammation en utilisant les 'interruptions' va me prendre un peu de temps.

A vos avis,

A suivre...

Little_Rabbit

Salut,

Effectivement, les #define ne doivent optimiser le code que très légèrement, et à mon avis ça ne coince pas au niveau de la vitesse d'exécution sur l'arduino, mais en temps de transmission aux AS1107. On voit clairement que si tu limites la trame à 3 matrices, ça passe nickel.

Pour moi, comme je le disais avant, il faut augmenter ta bande passante vers les matrices de diode, en limitant une trame à 3 modules, et en mettant en // plusieurs communications vers AS1107 (chaque canal n'adressant pas plus de 3 AS1107).

La communication avec un AS1107 se fait-elle par un port d'E/S générique, et reste-t-il d'autres ports de libre ?

Je n'ai pas détaillé le programme : que fait l'arduino entre 2 bits de la trame série envoyée aux l'AS1107, ou encore, à combien de bauds se fait la communication avec l'AS1107 ? => pour moi la solution est d'adresser successivement plusieurs groupes d'AS1107.

Actuellement, tu as :
P01 (1 port d'E/S de l'arduino) vers Din
Load CS\ vers tes 5 AS1107 chaînés les uns aux autres

la trame pour charger en série 5 matrices est trop longue.

Il faudrait à la place :
P01 vers Din1
Load CS1\ qui charge 3 AS1107

P02 vers Din2
Load CS2\ qui charge 2 autres AS1107

P03 vers Din3
Load CS3\ qui charge les oreilles

Dans ta boucle de communication avec les AS1107, à la place de

Répéter
  . placer un bit PO1
  . Abaisser CS\
  . attendre
  . relever CS\
  . décaler motif pour obtenir bit suivant
jusqu'à fin de ligne


il faudrait
Répéter
  . placer un bit PO1
  . placer un bit PO2
  . placer un bit PO3
  . Abaisser CS1\
  . Abaisser CS2\
  . Abaisser CS3\
  . attendre (moins longtemps qu'avant)
  . relever CS1\
  . relever CS2\
  . relever CS3\
  . décaler motif1 pour obtenir bit suivant
  . décaler motif2 pour obtenir bit suivant
  . décaler motif3 pour obtenir bit suivant
jusqu'à fin de ligne


Tout cela est bien sûr purement hypothétique car je ne sais pas du tout comment se fait la communication avec les AS1107  :-\ :). Mais j'imagine que l'arduino pédale beaucoup plus vite que la vitesse de communication avec les AS1107, et donc qu'il doit perdre du temps à attendre que l'AS1107 puisse recevoir le bit suivant. C'est ce temps qu'il faudra utiliser pour adresser en // plusieurs groupes plutôt que de tout envoyer en série depuis un seul canal :).

Si je suis complètement à côté de la plaque, faut me le dire :D.

A+
Recherche bornes dédiées ou PCB originaux: Miss Pacman, Dig Dug, Galaga, Mappy, Asteroids, Battlezone, Missile Command, Tempest, Star Wars, Donkey Kong (+ Jr), Mario Bros, Moon Patrol, Defender, Joust, Frogger, Gyruss, Pooyan, Space Tactics, Zaxxon, etc. Flip : Gottlieb des années 80 (Spirit, Amazon Hunt, ...), Baby Pac Man. Divers :  Ice Cold Beer => Trois fois rien quoi ! :D
Ma séance sur le divan : c'est grave Docteur ? :-\
Ma gaming room, ma storage room

tilowil

ton idée du l'adressage sur plusieurs bloc, c'est ce que j'utilise pour piloter 'façon interruption'. En fin de compte j'envoie à l'arduino une colonne à la fois. Comme j'ai un Arduino Mega, j'ai 54 pin d'E/S. Mais au final ce sera un Arduino Nano pour qu'il s'intègre facilement dans le casque, sauf contrainte de dernière minute.
Car on ne peux envoyer des informations qu'a une série d'AS1107 ou Max72xx à la fois. Chaque série d'AS1107 est relié à un buffer d'affichage correspondant au nombre de colonnes de la série (40 colonnes dans mon cas).
Chaque colonne ayant une valeur comprise entre 0 et 255 (lue en binaire et correspondant au nombre de leds allumée dans la colonne de la matrice).
L'inconvénient que je vois à ta solution, qui me semble malgré tout bonne, c'est qu'avec un module de 2 matrice je serait plus rapide qu'avec un module de 3 matrices (je vais le tester quand même avec prise de video). 

usagi

Je pense que le problème vient juste, de la fréquence d'écriture des AS1107. Si tu utilises deux chaines de drivers, tu as raison, tu risques de te prendre la tête pour synchroniser les deux.
La librairie que tu utilises semble écrire trop lentement dans les AS1107, je pense qu'en réécrivant seulement cette partie du code tu arrives à augmenter la vitesse d'écriture. Je t'aurais bien aider mais je n'ai rien pour tester :/ Mais je pense que la solution serait du côté des Fast PWM http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

// ------------------------------------------------------------------------------------
// Writes Data to a Register of the AS1106/AS1107
// chip: Number of the controller chip (starting at 0 for the left)
// reg:  Register of the controller
// data: Data to be written
void AS1107::WriteRegister( byte chip, byte reg,  byte data)
{
   if (chip>=0 && chip <= HighestCtrlNum) {
     chip = HighestCtrlNum -chip;
    [color=red] digitalWrite(_cspin,LOW);[/color]
     for (int i=0; i<=HighestCtrlNum; i++) {
     if (i == chip) {
       shiftOut(_datapin, _clkpin, MSBFIRST, reg);
       shiftOut(_datapin, _clkpin, MSBFIRST, data);
     }
     else {
      shiftOut(_datapin, _clkpin, MSBFIRST, Registers::NoOp);
       shiftOut(_datapin, _clkpin, MSBFIRST, 0);
     }
   }
     [color=red]digitalWrite(_cspin,HIGH);[/color]
   }
}


Pour la petite discussion sur le define/variable : si la variable est uniquement lue, le compilateur va s'en rendre compte et si il fait bien sont boulot optimisera le truc en remplaçant la variable par sa valeur. La seule différence entre le define et la variable, c'est que pour le define le remplacement sera fait à la pre-compilation tandis que la variable uniquement lue elle sera remplacée par le compilateur durant les phases d'optimisation.
Les compilo modernes font un boulot dingue sur l'optimisation.
Arcade: Astro City
Flipper : Space Jam

spectroman

Je connais pas du tout les arduinos, mais ne peux tu pas utiliser le port SPI pour écrire sur AS1107?


tilowil

Je me suis inscrit sur le MOOC que frenchcouze a annoncé sur le forum, car il y a de la programmation Arduino (entre autre), peut être que je vais y apprendre des astuces qui me sont encore inconnue, en tant que débutant en programmation Arduino.


Citation de: usagi le Mercredi 09 Avril 2014, 11:50:27 AM
Je pense que le problème vient juste, de la fréquence d'écriture des AS1107. Si tu utilises deux chaines de drivers, tu as raison, tu risques de te prendre la tête pour synchroniser les deux.
La librairie que tu utilises semble écrire trop lentement dans les AS1107, je pense qu'en réécrivant seulement cette partie du code tu arrives à augmenter la vitesse d'écriture. Je t'aurais bien aider mais je n'ai rien pour tester :/ Mais je pense que la solution serait du côté des Fast PWM http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

// ------------------------------------------------------------------------------------
// Writes Data to a Register of the AS1106/AS1107
// chip: Number of the controller chip (starting at 0 for the left)
// reg:  Register of the controller
// data: Data to be written
void AS1107::WriteRegister( byte chip, byte reg,  byte data)
{
   if (chip>=0 && chip <= HighestCtrlNum) {
     chip = HighestCtrlNum -chip;
    [color=red] digitalWrite(_cspin,LOW);[/color]
     for (int i=0; i<=HighestCtrlNum; i++) {
     if (i == chip) {
       shiftOut(_datapin, _clkpin, MSBFIRST, reg);
       shiftOut(_datapin, _clkpin, MSBFIRST, data);
     }
     else {
      shiftOut(_datapin, _clkpin, MSBFIRST, Registers::NoOp);
       shiftOut(_datapin, _clkpin, MSBFIRST, 0);
     }
   }
     [color=red]digitalWrite(_cspin,HIGH);[/color]
   }
}


Pour la petite discussion sur le define/variable : si la variable est uniquement lue, le compilateur va s'en rendre compte et si il fait bien sont boulot optimisera le truc en remplaçant la variable par sa valeur. La seule différence entre le define et la variable, c'est que pour le define le remplacement sera fait à la pre-compilation tandis que la variable uniquement lue elle sera remplacée par le compilateur durant les phases d'optimisation.
Les compilo modernes font un boulot dingue sur l'optimisation.
Merci usagi, oui tu as raison je devrais creuser les fast PWM. Je vais lire la littérature à tête reposée.
Mais je sais dejà que mes ports correspondent à :
23   PB4 ( OC2A/PCINT4 )   Digital pin 10 (PWM)
24   PB5 ( OC1A/PCINT5 )   Digital pin 11 (PWM)
25   PB6 ( OC1B/PCINT6 )   Digital pin 12 (PWM)


Citation de: spectroman le Mercredi 09 Avril 2014, 22:41:29 PM
Je connais pas du tout les arduinos, mais ne peux tu pas utiliser le port SPI pour écrire sur AS1107?
Je ne sais pas tous les exemples que j'ai pu trouver sur le net, ils écrivaient par le pin 10, 11, 12 qui sont des ports PWM (pouvant avoir des valeurs variables de 0 à 255 ce qui correspond aux valeurs que j'ai à transmettre.
Je ne m'y connais guère plus avec cette petite bête que je découvre au fur et à mesure de mes recherches :D.

Aujourd'hui je n'ai pas eu beaucoup de temps libre pour aller faire des tests. Je serais peut être plus tranquille ce week end.

Merci à vous tous, pour vos suggestions, n'hésitez pas à continuer de m'en déposer.