воскресенье, 21 апреля 2013 г.

NOKIA 5110 ARDUINO



На мой взгляд наиболее интересный дисплей, для подключения к ARDUINO, это дисплей от сотового телефона NOKIA 5110. 

Дисплей графический. Разрешение 48*84 пикселя. Выводить на него можно графическую или текстовую информацию. При этом шрифт и размер букв можно сделать любой. Он получил широкое распространение. Имеет необходимые библиотеки для работы и выпускается в виде готового модуля со стандартным разъемом и встроенной подсветкой.
Имеется много вариантов модуля. Основные различия: распиновка, подсветка (нет, есть, есть, но без резисторов), наличие возможности установки разъема с двух сторон.



Я буду рассматривать вариант у которого подсветка уже имеет токоограничивающие резисторы


 Перемычка JP1 включает подсветку освобождая один провод
 Подключаем модуль по следующей схеме


//     5110     ARDUINO
//  Pin 1 - RST  - Pin 12
//  Pin 2 - CE   - Pin 11
//  Pin 3 - DC   - Pin 10
//  Pin 4 - DIN  - Pin 9
//  Pin 5 - CLK  - Pin 8
//  Pin 6      -       3.3V     
//  Pin 7 - LIGHT -GND
//  Pin 8      -       GND   


 Для работы потребуется библиотека из архива, работает с Arduino 1.0

Основные функции

1. Текст
myGLCD.print("PROBA", CENTER, 0);

Выводит надпись PROBA начиная с "0" строки по центру (варианты LEFT, CENTER, RIGHT). Если указать номер строки например 44, то мы увидим только верхнюю половину букв. Для вывода цифровых переменных используется функция

myGLCD.printNumI(DHT11.humidity, CENTER, 20);

2. Линии
myGLCD.drawLine(0, 0, 83, 47);

Рисует диагональ

3. Прямоугольник

myGLCD.drawRect(26, 16, 58, 30);

Рисует прямоугольник в центре экрана длиной 32 и высотой 14 пикселей. Команда drawRoundRect рисует прямоугольник с закругленными краями

4. Окружность

myGLCD.drawCircle(41, 23, 28);

Рисует окружность в центре экрана (41, 23) радиусом 28, поэтому мы увидим две дуги слева и справа, верх и низ "за кадром". Пиксели не квадратные, они вытянуты вверх. Поэтому и огружность вытянута по вертикали. 

5. Очистка экрана

myGLCD.clrScr();

6. Вывод картинки

extern uint8_t video[];
myGLCD.drawBitmap(0, 0, video, 84, 48);

Картинка кодируется в массив из 84*48=504 чисел. Каждое число отвечает за колонку из 8 пикселей. Для примера число 8F (HEX) = 143 (DEC) = 10001111 (BIN) будет выглядеть на экране следующим образом (Ж-пиксель горит, . - пиксель погашен)

Ж
Ж
Ж
Ж
.
.
.
Ж

В примере массив video записан так

uint8_t video[] PROGMEM={
0x00,0x00,0x00,0x00,0x00,0xFC,0x08,0x30,0x08,0xFC,0x00,0x78,0x84,0x84,0x84,
0x48,0x00,0x7C,0x80,0x80,0x80,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFC,0x24,0x24,0x24,0xD8,0x00,0x78,0x84,0x84,0x84,0x48,
0x00,0xF0,0x28,0x24,0x28,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x04,0x04,
0x84,0x84,0x84,0x84,0x04,0x84,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
0x1F,0x00,0x00,0x1F,0x04,0x0A,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0xFC,0x00,0x00,0x00,0x00,0xFF,0x00,0x23,0x24,0x24,0x24,0x18,0x00,0x3E,
0x00,0x3E,0x04,0x02,0x3C,0x00,0x1C,0x22,0x22,0x22,0x00,0xFF,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x1F,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
0x11,0x11,0x11,0x1F,0x04,0x04,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,
0x00,0xE0,0x00,0x20,0x20,0xA0,0x60,0x00,0xC0,0x20,0x20,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x70,0xFF,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFF,
0x00,0x7C,0x80,0x00,0x80,0x7C,0x00,0x04,0xFC,0x04,0x00,0xFC,0x04,0x04,0x04,
0xF8,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xC0,0x00,
0x00,0x00,0xC0,0x00,0x40,0xC0,0x40,0x00,0xC0,0x40,0x40,0x40,0x80,0x00,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x81,0x81,0x8F,0x80,0x80,0x8F,0x80,
0x80,0x80,0x87,0x88,0x88,0x87,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0xFF,0x00,
0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x07,0x08,0x10,0x08,0x07,0x00,0x10,0x1F,
0x10,0x00,0x1F,0x10,0x10,0x10,0x0F,0x00,0x1F,0x02,0x02,0x02,0x02,0x02,0x02,
0x02,0x02,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
0x0F,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,
};

и выводит на экран кусочек схемы подключения ARDUINO к ТВ
Кодировал картинку в массив при помощи самостоятельно написанного макроса для EXCEL. Просто и доступно практически каждому. (можно посмотреть в архиве)

Пока архив не создан предлагаю ознакомится с примером использования практически всех функций


//     5110    ARDUINO
//  Pin 1 - RST  - Pin 12
//  Pin 2 - CE   - Pin 11
//  Pin 3 - DC   - Pin 10
//  Pin 4 - DIN  - Pin 9
//  Pin 5 - CLK  - Pin 8
//  Pin 6 - 3.3V     
//  Pin 7 - GND
//  Pin 8 - GND    
//
#include <LCD5110_Graph.h>

LCD5110 myGLCD(8,9,10,12,11);

extern uint8_t SmallFont[];
extern uint8_t arduino_logo[];
extern unsigned char TinyFont[];
extern uint8_t The_End[];
extern uint8_t pacman1[];
extern uint8_t pacman2[];
extern uint8_t pacman3[];
extern uint8_t pill[];

float y;
uint8_t* bm;
int pacy;

void setup()
{
  myGLCD.InitLCD(); // в качестве параметра можно указать контрастность (0-127), по умолчанию 79
  myGLCD.setFont(TinyFont);
  randomSeed(analogRead(7));
}

void loop()
{
  myGLCD.clrScr();
  myGLCD.drawBitmap(0, 0, arduino_logo, 84, 48);
  myGLCD.update();

  delay(2000);
  
  myGLCD.clrScr();
  myGLCD.print("LCD5110_Graph", CENTER, 0);
  myGLCD.print("DEMO", CENTER, 20);
  myGLCD.drawRect(28, 18, 56, 28);
  for (int i=0; i<6; i++)
  {
    myGLCD.drawLine(57, 18+(i*2), 83-(i*3), 18+(i*2));
    myGLCD.drawLine((i*3), 28-(i*2), 28, 28-(i*2));
  }
  myGLCD.setFont(TinyFont);
  myGLCD.print("(C)2013 by", CENTER, 36);
  myGLCD.print("Henning Karlsen", CENTER, 42);
  myGLCD.update();
  
  delay(5000);
  
  myGLCD.clrScr();
  for (int i=0; i<48; i+=6)
  {
    myGLCD.drawLine(0, i, 83, 47-i);
    myGLCD.update();
  }
  for (int i=83; i>=0; i-=6)
  {
    myGLCD.drawLine(i, 0, 83-i, 47);
    myGLCD.update();
  }

  delay(2000);
  
  myGLCD.clrScr();
  myGLCD.drawRect(0, 0, 83, 47);
  for (int i=0; i<48; i+=6)
  {
    myGLCD.drawLine(0, i, i*1.75, 47);
    myGLCD.update();
  }
  for (int i=0; i<48; i+=6)
  {
    myGLCD.drawLine(83, 47-i, 83-(i*1.75), 0);
    myGLCD.update();
  }

  delay(2000);
  
  myGLCD.clrScr();
  for (int i=0; i<8; i++)
  {
    myGLCD.drawRoundRect(i*3, i*3, 83-(i*3), 47-(i*3));
    myGLCD.update();
  }

  delay(2000);
  
  myGLCD.clrScr();
  for (int i=0; i<17; i++)
  {
    myGLCD.drawCircle(41, 23, i*3);
    myGLCD.update();
  }

  delay(2000);
  
  myGLCD.clrScr();
  myGLCD.drawRect(0, 0, 83, 47);
  myGLCD.drawLine(0, 23, 84, 23);
  myGLCD.drawLine(41, 0, 41, 47);
  for (int c=0; c<4; c++)
  {
    for (int i=0; i<84; i++)
    {
      y=i*0.017453292519943295769236907684886;
      myGLCD.invPixel(i, (sin(y*6)*20)+23);
      myGLCD.update();
      delay(20);
    }
  }

  delay(2000);

  for (int pc=0; pc<3; pc++)
  {
    pacy=random(0, 28);
  
    for (int i=-20; i<84; i++)
    {
      myGLCD.clrScr();
      for (int p=4; p>((i+20)/20); p--)
        myGLCD.drawBitmap(p*20-8, pacy+7, pill, 5, 5);
      switch(((i+20)/3) % 4)
      {
        case 0: bm=pacman1;
                break;
        case 1: bm=pacman2;
                break;
        case 2: bm=pacman3;
                break;
        case 3: bm=pacman2;
                break;
      }
      myGLCD.drawBitmap(i, pacy, bm, 20, 20);
      myGLCD.update();
      delay(25);
    }
  }

  for (int i=0; i<25; i++)
  {
    myGLCD.clrScr();
    myGLCD.drawBitmap(0, i-24, The_End, 84, 24);
    myGLCD.update();
    delay(100);
  }
  myGLCD.setFont(SmallFont);
  myGLCD.print("Runtime (ms):", CENTER, 32);
  myGLCD.printNumI(millis(), CENTER, 40);
  myGLCD.update();
  for (int i=0; i<5; i++)
  {
    myGLCD.invert(true);
    delay(1000);
    myGLCD.invert(false);
    delay(1000);
  }
}

Отдельно описываются графические массивы graphics.c
#include <avr/pgmspace.h>

uint8_t arduino_logo[] PROGMEM={
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC,   // 0x0010 (16) pixels
0xFE, 0xFE, 0x7F, 0x7F, 0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0xFE, 0xFE, 0xFE,   // 0x0020 (32) pixels
0xFC, 0xFC, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0,   // 0x0030 (48) pixels
0xF0, 0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, 0x7F, 0x7F, 0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F,   // 0x0040 (64) pixels
0x7F, 0x7F, 0x7F, 0xFE, 0xFE, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xE0, 0xC0, 0x86, 0x06, 0x06, 0x00,   // 0x0050 (80) pixels
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0060 (96) pixels
0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,   // 0x0070 (112) pixels
0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x03, 0x0F, 0x1F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFE,   // 0x0080 (128) pixels
0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F, 0x03, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xF8,   // 0x0090 (144) pixels
0xF8, 0xF8, 0xF8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x1F, 0xFF, 0xFF, 0xFF,   // 0x00A0 (160) pixels
0xFF, 0xFF, 0xFC, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x7F, 0xFF,   // 0x00B0 (176) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07,   // 0x00C0 (192) pixels
0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xF0, 0xF8, 0xFE, 0xFF,   // 0x00D0 (208) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xF0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07,   // 0x00E0 (224) pixels
0x07, 0x07, 0x07, 0x3F, 0x3F, 0x3F, 0x3F, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,   // 0x00F0 (240) pixels
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // 0x0100 (256) pixels
0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFC, 0xFC,   // 0x0110 (272) pixels
0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, 0xFE, 0xFF, 0x7F, 0x7F, 0x3F, 0x3F,   // 0x0120 (288) pixels
0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x3F, 0x7F,   // 0x0130 (304) pixels
0x7F, 0xFF, 0xFE, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xFC, 0xFC, 0xFE,   // 0x0140 (320) pixels
0xFE, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // 0x0150 (336) pixels
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00,   // 0x0160 (352) pixels
0x00, 0x00, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0x81, 0x81, 0x01, 0x01, 0xC1, 0xC1, 0xC0, 0xC0,   // 0x0170 (368) pixels
0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x80, 0x00,   // 0x0180 (384) pixels
0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC1, 0xC1, 0x01, 0x01, 0xC1, 0xC1, 0xC1, 0x01, 0x01,   // 0x0190 (400) pixels
0x01, 0xC1, 0xC1, 0x01, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0x00, 0x00, 0x00,   // 0x01A0 (416) pixels
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF8, 0xFF, 0x3F, 0x3B,   // 0x01B0 (432) pixels
0x3F, 0x7F, 0xFE, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1C, 0x3C, 0xFF, 0xFF, 0xC7, 0x00, 0x00,   // 0x01C0 (448) pixels
0xFF, 0xFF, 0xFF, 0xE0, 0xE0, 0xF1, 0x7F, 0x3F, 0x1F, 0x00, 0x3F, 0x7F, 0xFF, 0xE0, 0xC0, 0xE0,   // 0x01D0 (464) pixels
0xFF, 0x7F, 0x3F, 0x00, 0x00, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xE0, 0xC0, 0x00, 0x00, 0xFF,   // 0x01E0 (480) pixels
0xFF, 0x07, 0x0F, 0x3E, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0x7F, 0xFF, 0xE0, 0xC0, 0xE1, 0x7F,   // 0x01F0 (496) pixels
0x7F, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

uint8_t The_End[] PROGMEM={
0x00, 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0x60, 0x00, 0x00,   // 0x0010 (16) pixels
0x80, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0,   // 0x0020 (32) pixels
0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0,   // 0x0030 (48) pixels
0xE0, 0xC0, 0xC0, 0xC0, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0x00, 0x00,   // 0x0040 (64) pixels
0x00, 0x00, 0x80, 0xE0, 0xF0, 0xF0, 0x60, 0x40, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0xC0,   // 0x0050 (80) pixels
0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x81, 0xFC, 0xFF, 0x0F, 0x03, 0x00, 0x00, 0x00,   // 0x0060 (96) pixels
0xEE, 0x6F, 0x67, 0xFF, 0xFF, 0x7F, 0x71, 0x30, 0xF0, 0xFF, 0x3F, 0x39, 0x38, 0x18, 0x00, 0x01,   // 0x0070 (112) pixels
0x00, 0xF8, 0xFF, 0x1F, 0x0F, 0x0C, 0x0D, 0x8D, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,   // 0x0080 (128) pixels
0x00, 0xC0, 0xFF, 0x7F, 0x0F, 0x0C, 0x0D, 0x0D, 0x84, 0x80, 0x80, 0x07, 0x07, 0x83, 0xFF, 0xFF,   // 0x0090 (144) pixels
0x1F, 0x3F, 0xFE, 0xF8, 0xF8, 0xFE, 0xDF, 0x03, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x1F, 0x00,   // 0x00A0 (160) pixels
0x00, 0x80, 0x81, 0xC3, 0xE7, 0x7F, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x06, 0x07, 0x07, 0x03, 0x00,   // 0x00B0 (176) pixels
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x0F, 0x0F, 0x07, 0x00,   // 0x00C0 (192) pixels
0x00, 0x06, 0x06, 0x3F, 0x1F, 0x0F, 0x0F, 0x0E, 0x06, 0x06, 0x06, 0x07, 0x07, 0x03, 0x00, 0x00,   // 0x00D0 (208) pixels
0x00, 0x00, 0x06, 0x1F, 0x3F, 0x1F, 0x0F, 0x0E, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x03, 0x00,   // 0x00E0 (224) pixels
0x06, 0x0F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x18, 0x1C, 0x1F,   // 0x00F0 (240) pixels
0x0F, 0x07, 0x06, 0x07, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
};

uint8_t pacman1[] PROGMEM={
0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3E, 0x1C,   // 0x0010 (16) pixels
0x0C, 0x00, 0x00, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9,   // 0x0020 (32) pixels
0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x00, 0x00, 0x00,
};

uint8_t pacman2[] PROGMEM={
0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7C,   // 0x0010 (16) pixels
0x7C, 0x38, 0x20, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9,   // 0x0020 (32) pixels
0xF9, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00,
};

uint8_t pacman3[] PROGMEM={
0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFC,   // 0x0010 (16) pixels
0xF8, 0xF0, 0xE0, 0x80, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0020 (32) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xF9, 0x79, 0x19, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00,
};

uint8_t pill[] PROGMEM={
0x0E, 0x1F, 0x1F, 0x1F, 0x0E,
};

пятница, 1 марта 2013 г.

1602 LED ARDUINO


Подключаем дисплей 1602 к ARDUINO

1602 означает 16 символов в 2-х строках. Аналогично подключается дисплей 2004 (20 символов в 4-х строках).
Цвет подсветки бывает разный. Стоимость 175 руб






Подключаем по схеме. Переменным резистором подстраиваем контрастность. Используем библиотеку LiquidCrystal.h

Русского языка в наборе символов нет. Поэтому используем функцию lcd.createChar для создания собственных символов. Например «Й».

// 1602 (С)2013 ALEN Studio by Little_Red_Rat

// Подключаем дисплей 1602 к ARDUINO

// Подключаем библиотеку для работы с LCD
#include <LiquidCrystal.h>
// Указываем, к каким пинам Arduino подключены выводы дисплея:
// RS, E, DB4, DB5, DB6, DB7

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Рисуем букву Й
byte I_kr_lit[8] =
{
  B00100,
  B10101,
  B10001,
  B10011,
  B10101,
  B11001,
  B10001,
  B00000,
};



void setup()
{
// Создаем собственный символ номер 2
  lcd.createChar(2, I_kr_lit);
// Инициализируем дисплей: 2 строки по 16 символов
  lcd.begin(16, 2);
// Устанавливаем курсор в 1-й столбец 1-й строки. Нумерация идёт с нуля, сначала столбец
  lcd.setCursor(0, 0);
// Выводим на дисплей АЙ-ОЙ, буквы А и О английские
  lcd.print("A\2-O\2");
}

void loop()
{
// Устанавливаем курсор в 1-й столбец 2-й строки.  
 lcd.setCursor(0, 1);
// Выводим на дисплей число секунд, прошедших с момента старта Arduino
 lcd.print(millis() / 1000);
}

вторник, 12 февраля 2013 г.

ARDUINO омметр


ARDUIO первый полезный проект

Для реализации данного способа подключения потребуется:

·        1 * резистор 10 кОм (100 руб за набор из 95 штук)
·        Разъем на 5 pin «мама» (25 руб за линейку из 40 штук)

Цены взяты с сайта МОЛОТОК.РУ

Иногда, после творения очередного проекта остается куча резисторов, которые нужно разобрать обратно по местам, согласно маркировки. Проблема в том, что современные резисторы имеют маркировку в виде цветных полос. В отличии от советских резисторов, на которых был написан номинал.
Можно сверять цветную маркировку с таблицами в интернете или использовать программу установленную на ANDROID телефоне. Мне показалось это не удобно.

Я решил сделать небольшой проект «ARDUINO омметр». Наверно всем известен делитель напряжения. Вкратце: падение напряжения на резисторе зависит от его сопротивления. Смотрим схему.


ARDUINO имеет аналоговый вход. При чтении с него возвращается значение от 0 до 1023. Собираем схемку.

На одном плече резистор 10 кОм, ко второму плечу подключаем резистор, сопротивление которого нужно измерить.  Среднюю точку подключаем к аналоговому входу A0.
Загружаем скетч. 

// ОММЕТР (С)2013 ALEN Studio by Little_Red_Rat

// Омметр на осное ARDUINO
//
// Подключение делителя напряжения к ARDUINO
// Arduino 5V -> R1 10kOm -> Arduino Analog 0 -> R2 -> Arduino GND

int analogPin = 0; // Анлоговый вход для считывания напряжения с делителя напряжения
float Vout = 0; // Переменная для хранения значения напряжения в средней точки делителя (0-5.0)

float R2 = 0; // Переменная для хранения значения резистора R2

void setup() 

Serial.begin(9600); // Подготовка Serial Monitor для вывода информации


void loop() 

Vout = (5.0 / 1023.0) * analogRead(analogPin); // Вычисляем напряжение в средней точки делителя (0-5.0)
R2 = 10000 / ((5.0 / Vout) - 1); // Вычисляем сопротивление R2 (10000 это значение R1 10 кОм) 
Serial.print("Voltage: "); // 
Serial.println(Vout); // Напряжения в средней точки делителя (0-5.0) для справки
Serial.print("R2: "); // 
Serial.println(R2); // Значение сопротивления R2

delay(1000); // Пауза 1 сек
}


Включаем Serial Monitor. Раз в 1 секунду мы видим напряжение в средней точке делителя и рассчитанное сопротивление.

Для примера измерено сопротивление резистора, который имеет маркировку 10 кОм. Результат работы удовлетворителен. Но если R2 будет намного больше или меньше, чем R1, погрешность возрастет. Составим таблицу. Показания на аналоговом входе могут изменятся от 0 до 1023. Посмотрим чему будет равно расчетное значение сопротивления R2 для некоторых значений U2.

U2 U1 R1 R2 шаг  в %
1 1023 10000 10
2 1022 10000 20 100
3 1021 10000 29 50
4 1020 10000 39 33
5 1019 10000 49 25
6 1018 10000 59 20
7 1017 10000 69 17
502 522 10000 9617
503 521 10000 9655 0.39
504 520 10000 9692 0.39
505 519 10000 9730 0.39
506 518 10000 9768 0.39
507 517 10000 9807 0.39
1017 7 10000 1452857
1018 6 10000 1696667 17
1019 5 10000 2038000 20
1020 4 10000 2550000 25
1021 3 10000 3403333 33
1022 2 10000 5110000 50
1023 1 10000 10230000 100

Как видно из сокращенной таблицы шаг измерения наименьший в середине диапазона. Это значит, что чем ближе значения R1 и R2, тем результат измерения наиболее точен.
Значит не напрасно в цифровых мультиметрах существует несколько диапазонов для измерения сопротивления. Что можно сделать в нашем случае. Переключатель ставить не хочется. Попробуем использовать несколько аналоговых входов. 

Далее идет чистая теория, не опробованная на практике.

Попробуем собрать схему с несколькими делителями напряжения. Подключим измеряемое сопротивление к GND и к одному из аналоговых входов. Чем ближе значение его сопротивления будет к значению сопротивлению подключенного от этого же входа к 5V, тем точнее будет результат измерения.

В программе нужно реализовать следующие функции.

1.   Определение, к какому входу подключено сопротивление. На этом входе значение будет отличным от 1023 (5V), т.к. при отсутствии R2 в делителе в средней точке будет 5V.
2.   Определение, в какой части диапазона находится значение напряжения. Если в начале или в конце диапазона (например 0-256 или 768-1023) ,предложить подключить сопротивление на соседний вход
3.   Рассчитать сопротивление, исходя из значения R1 подключенного к входу, определенному в пункте 1.

Это уже вы как-нибудь самостоятельно, без меня

Для красоты можно добавить дисплей и ввести таблицу стандартных значений резисторов и подводить измеренное сопротивление под стандарт
Класс точности 10%, ряд Е12 по ГОСТу (Ом, кОм, МОм):
1.0, 1.2, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2, 10, 12, 15, 18, 22, 27, 33, 39, 47, 56, 68, 82, 100, 120, 150, 180, 220, 270, 330, 390, 470, 560, 680, 820


Большая просьба к любителям перепостов, указывать автора Little_Red_Rat