arduino a multiplexovaný displej

Jaroslav Lukesh lukesh na seznam.cz
Neděle Leden 4 19:24:54 CET 2015


Ano.

startpage.com mi dává lepší výsledky hledání než google, použijte jej.

používá se to u TV-out, u 8x8 matic, u 7-segment multiplexu, u rotačních 
enkodérů, jen musíte všecky postahovat a najít tu správnou knihovnu, hnoje 
je spousta i mezi oficiálně doporučovanými... Třeba tohle zrovna takovou 
slušnou knihovnu na čtení enkodérů používá:

http://forum.arduino.cc/index.php?topic=275248.msg1938244#msg1938244

Tady tohle malovátko taky používá multiplex:


/*
 http://blog.bsoares.com.br/arduino/ping-pong-with-8x8-led-matrix-on-arduino
 http://playground.arduino.cc/uploads/Main/Matrix.gif
 princip: http://arduino.cc/en/Tutorial/RowColumnScanning
=============================================
COMMON ANODE display

  6  7  8  9  10 11 12 13
  o  o  o  o  o  o  o  o
 |                       |
 |                       |
 |                       |
 |                       |
 |                       |
 |                       |
 |                       |
 |                       |
  o  o  o  o  o  o  o  o
  5  4  3  2  A0 A1 A2 A3

 Potenciometry +Vcc/GND - L:A7, R:A6   MOD: 16,17, Beeper: A4
 Tlačítka na A5 čtou se analogově, nutno zapnout PULLUP. Z A5 je také 
zapojen R=47k na GND
 + ----TL---R1k--A5-TL---GND
 Levé je stisknuto => vstup > 700
 Pravé stisknuto = vstup < 300

 Napájení přes li-ion na RAW

=============================================
*/

#include "TimerOne.h"

#define PIN_LEFT 7
#define PIN_RIGHT 6
#define BEEPER A4
#define TLAC A5

unsigned int left = 0;
unsigned int right = 0;
unsigned int left_OLD = 0;
unsigned int right_OLD = 0;
unsigned int tlac = 512;

byte rows[8] = {9, 14, 8, 12, 1, 7, 2, 5};
byte cols[8] = {13, 3, 4, 10, 6, 11, 15, 16};
byte pins[16] = {5, 4, 3, 2, 14, 15, 16, 17, 13, 12, 11, 10, 9, 8, 7, 6};
byte screen[8] = {0, 0, 0, 0, 0, 0, 0, 0};
volatile byte screenRow = 0;
volatile byte screenCol = 0;

int _px;
int _py;
int _w = 7;
int _h = 7;

byte blinker = 0;
byte sviti = 0;

void setup() {
  Timer1.initialize(100);
  for (int i = 2; i <= 17; i++)
    pinMode(i, OUTPUT);
  Timer1.attachInterrupt(doubleBuffer);

  //Serial.begin(9600);

  pinMode(BEEPER, OUTPUT);
  digitalWrite(BEEPER, 0); //pípák mezi pinem a zemí

  pinMode(TLAC, INPUT_PULLUP);

  heart();
  left = 7-constrain(map(analogRead(PIN_LEFT), 223, 800, 0, 7), 0, 7);
  right = constrain(map(analogRead(PIN_RIGHT), 223, 800, 7, 0), 0, 7);
}

void loop() {
  maluj();
}
// ====================================================================

void doubleBuffer() {
  digitalWrite(translatePin(rows[screenRow]), HIGH);
  digitalWrite(translatePin(cols[screenCol]), LOW);

  screenCol++;
  if (screenCol >= 8) {
    screenCol = 0;
    screenRow++;
    if (screenRow >= 8) {
      screenRow = 0;
    }
  }

  if((screen[screenRow] >> screenCol) & B1 == B1) {
    digitalWrite(translatePin(rows[screenRow]), LOW);
    digitalWrite(translatePin(cols[screenCol]), HIGH);
  } else {
    digitalWrite(translatePin(rows[screenRow]), HIGH);
    digitalWrite(translatePin(cols[screenCol]), LOW);
  }
}

byte translatePin(byte original) {
  return pins[original - 1];
}

void allOFF() {
  for (int i = 0; i < 8; i++)
    screen[i] = 0;
}

void M_on(byte row, byte column) {
    screen[column] |= (B1 << (row));
}

void M_off(byte row, byte column) {
    screen[column] &= ~(B1 << (row));
}


void heart(){
    tone(BEEPER, 8192,5);
    screen[0] = B00000000;
    screen[1] = B00000110;
    screen[2] = B00001001;
    screen[3] = B00010001;
    screen[4] = B00100010;
    screen[5] = B00010001;
    screen[6] = B00001001;
    screen[7] = B00000110;
    delay(1000);
    allOFF();
    tone(BEEPER, 4096,5);
}

void maluj()
{
  left_OLD = left;
  right_OLD = right;
  left = 7-constrain(map(analogRead(PIN_LEFT), 223, 800, 0, 7), 0, 7);
  right = constrain(map(analogRead(PIN_RIGHT), 223, 800, 7, 0), 0, 7);
  tlac =  analogRead(TLAC);

  if (tlac < 256){sviti=0;}
  else
  if (tlac > 800){heart();sviti=1;}
  else{sviti=1;}

  if((left_OLD == left and right_OLD == right) and sviti == 0 and blinker<<2 
<128) {M_off(left_OLD,right_OLD);}
  else
  if((left_OLD == left and right_OLD == right) and sviti == 0 and blinker<<2 
 >=128) {M_on(left_OLD,right_OLD);}
  else
  if((left_OLD == left and right_OLD == right) and sviti == 1 and blinker<<2 
<128) {M_off(left_OLD,right_OLD);}
  else
  if((left_OLD == left and right_OLD == right) and sviti == 1 and blinker<<2 
 >=128) {M_on(left_OLD,right_OLD);}
  else

  if((left_OLD != left or right_OLD != right) and sviti == 0 and blinker<<2 
<128) {M_off(left_OLD,right_OLD);}
  else
  if((left_OLD != left or right_OLD != right) and sviti == 0 and blinker<<2 
 >=128) {M_off(left_OLD,right_OLD);}
  else
  if((left_OLD != left or right_OLD != right) and sviti == 1 and blinker<<2 
<128) {M_on(left_OLD,right_OLD);}
  else
  if((left_OLD != left or right_OLD != right) and sviti == 1 and blinker<<2 
 >=128) {M_on(left_OLD,right_OLD);}

  blinker++;

}




----- Původní zpráva ----- 
Od: "Petr Zapadlo" <zapik na email.cz>

existuje u běžných arduin (atmega 328) možnost pravidelného přerušení od
časovače?

Chtěl bych ovládat multiplexovaný displej s tím, že arduino má dělat
ještě cosi jiného (např komunikovat s esp8266) a  některé funkce jsou
blokující. V takovém případě napsat kod, který udrží slušné zobrazení na
displeji je hrozný opruz.

Jak se to dá řešit?



Další informace o konferenci Hw-list