PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Minestation.pde

https://github.com/radikalbytes/minestation
Processing | 1704 lines | 1021 code | 143 blank | 540 comment | 147 complexity | 532c12e540de077e1b025a5fd0e391bd MD5 | raw file
  1. #include <TimerOne.h>
  2. // Compatiblity with Arduino IDE 1.0
  3. // Arduino API used in v.22 libraries
  4. // is WProgram.h
  5. // and in v1.0 it's renamed to Arduino.h
  6. #if defined(ARDUINO) && ARDUINO >= 100
  7. #include "Arduino.h"
  8. #else
  9. #include "WProgram.h"
  10. #endif
  11. /****************************************************/
  12. /* Example Program For LCD6610 (NPX) */
  13. /* MCU : Arduino Nano */
  14. /* By : Gravitech */
  15. /* Function : Demo Interface LCD6610 */
  16. /* (Philips controller) */
  17. /****************************************************/
  18. /* Interface LCD6610 to Arduino Nano */
  19. /* Nano --> LCD6610 */
  20. /* D2 --> BL */
  21. /* D3 --> #CS */
  22. /* D4 --> SCLK */
  23. /* D5 --> SDATA */
  24. /* D6 --> #RESEET */
  25. /* +5V --> VCC,VBL */
  26. /* GND --> GND */
  27. /****************************************************/
  28. #include <avr/pgmspace.h>
  29. #include "foto.h"
  30. #include "fonts.h"
  31. #include <TimerOne.h>
  32. /* Define LCD6610 PinIO interface */
  33. //#define BL 2 // Digital 2 --> BL
  34. #define CS 10 //3 // Digital 3 --> #CS
  35. #define CLK 13 // 4 // Digital 4 --> SCLK
  36. #define SDA 11 // 5 // Digital 5 --> SDATA
  37. #define RESET 9 // 6 // Digital 6 --> #RESET
  38. /* Start of Define Philips(NXP):PCF8833 Header */
  39. #define NOP 0x00 // nop
  40. #define SWRESET 0x01 // software reset
  41. #define BSTROFF 0x02 // booster voltage OFF
  42. #define BSTRON 0x03 // booster voltage ON
  43. #define RDDIDIF 0x04 // read display identification
  44. #define RDDST 0x09 // read display status
  45. #define SLEEPIN 0x10 // sleep in
  46. #define SLEEPOUT 0x11 // sleep out
  47. #define PTLON 0x12 // partial display mode
  48. #define NORON 0x13 // display normal mode
  49. #define INVOFF 0x20 // inversion OFF
  50. #define INVON 0x21 // inversion ON
  51. #define DALO 0x22 // all pixel OFF
  52. #define DAL 0x23 // all pixel ON
  53. #define SETCON 0x25 // write contrast
  54. #define DISPOFF 0x28 // display OFF
  55. #define DISPON 0x29 // display ON
  56. #define CASET 0x2A // column address set
  57. #define PASET 0x2B // page address set
  58. #define RAMWR 0x2C // memory write
  59. #define RGBSET 0x2D // colour set
  60. #define PTLAR 0x30 // partial area
  61. #define VSCRDEF 0x33 // vertical scrolling definition
  62. #define TEOFF 0x34 // test mode
  63. #define TEON 0x35 // test mode
  64. #define MADCTL 0x36 // memory access control
  65. #define SEP 0x37 // vertical scrolling start address
  66. #define IDMOFF 0x38 // idle mode OFF
  67. #define IDMON 0x39 // idle mode ON
  68. #define COLMOD 0x3A // interface pixel format
  69. #define SETVOP 0xB0 // set Vop
  70. #define BRS 0xB4 // bottom row swap
  71. #define TRS 0xB6 // top row swap
  72. #define DISCTR 0xB9 // display control
  73. //#define DAOR 0xBA // data order(DOR)
  74. #define TCDFE 0xBD // enable/disable DF temperature compensation
  75. #define TCVOPE 0xBF // enable/disable Vop temp comp
  76. #define EC 0xC0 // internal or external oscillator
  77. #define SETMUL 0xC2 // set multiplication factor
  78. #define TCVOPAB 0xC3 // set TCVOP slopes A and B
  79. #define TCVOPCD 0xC4 // set TCVOP slopes c and d
  80. #define TCDF 0xC5 // set divider frequency
  81. #define DF8COLOR 0xC6 // set divider frequency 8-color mode
  82. #define SETBS 0xC7 // set bias system
  83. #define RDTEMP 0xC8 // temperature read back
  84. #define NLI 0xC9 // n-line inversion
  85. #define RDID1 0xDA // read ID1
  86. #define RDID2 0xDB // read ID2
  87. #define RDID3 0xDC // read ID3
  88. #ifdef PB1
  89. #define LCD_CS(x) PORTB= (x)? (PORTB|(1<<PB2)) : (PORTB&~(1<<PB2))
  90. #define LCD_CLK(x) PORTB= (x)? (PORTB|(1<<PB5)) : (PORTB&~(1<<PB5))
  91. #define LCD_DATA(x) PORTB= (x)? (PORTB|(1<<PB3)) : (PORTB&~(1<<PB3))
  92. #define LCD_RESET(x) PORTB= (x)? (PORTB|(1<<PB1)) : (PORTB&~(1<<PB1))
  93. #define LCD_levelLight(x) PORTB= (x)? (PORTB|(1<<PB0)) : (PORTB&~(1<<PB0))
  94. #else
  95. #define LCD_CS(x) PORTB= (x)? (PORTB|(1<<PORTB2)) : (PORTB&~(1<<PORTB2))
  96. #define LCD_CLK(x) PORTB= (x)? (PORTB|(1<<PORTB5)) : (PORTB&~(1<<PORTB5))
  97. #define LCD_DATA(x) PORTB= (x)? (PORTB|(1<<PORTB3)) : (PORTB&~(1<<PORTB3))
  98. #define LCD_RESET(x) PORTB= (x)? (PORTB|(1<<PORTB1)) : (PORTB&~(1<<PORTB1))
  99. #define LCD_levelLight(x) PORTB= (x)? (PORTB|(1<<PORTB0)) : (PORTB&~(1<<PORTB0))
  100. #endif
  101. #define LCDCommand 0
  102. #define LCDData 1
  103. // Font sizes
  104. #define SMALL 0
  105. #define MEDIUM 1
  106. #define LARGE 2
  107. // Booleans
  108. #define NOFILL 0
  109. #define FILL 1
  110. // 12-bit color definitions
  111. // Mode color BGR 多?多 I don't know but works
  112. #define WHITE 0xFFF
  113. #define BLACK 0x000
  114. #define RED 0x00F //0xF00
  115. #define GREEN 0x0F0
  116. #define BLUE 0xF00 //0x00F
  117. #define CYAN2 0xF70
  118. #define CYAN 0xFF0 //0x0FF
  119. #define MAGENTA 0xF0F
  120. #define YELLOW 0x0FF //0xFF0
  121. #define BROWN 0x22B //0xB22
  122. #define ORANGE 0x0AF //0xFA0
  123. #define PINK 0xA6F //0xF6A
  124. #define GREY 0xCCC
  125. #define cbi(reg, bit) (reg&=~(1<<bit))
  126. #define sbi(reg, bit) (reg|= (1<<bit))
  127. #define CS0 cbi(PORTD,CS);
  128. #define CS1 sbi(PORTD,CS);
  129. #define CLK0 cbi(PORTD,CLK);
  130. #define CLK1 sbi(PORTD,CLK);
  131. #define SDA0 cbi(PORTD,SDA);
  132. #define SDA1 sbi(PORTD,SDA);
  133. #define RESET0 cbi(PORTD,RESET);
  134. #define RESET1 sbi(PORTD,RESET);
  135. #define BL0 cbi(PORTD,BL);
  136. #define BL1 sbi(PORTD,BL);
  137. /* End of Define Philips(NXP):PCF8833 Header */
  138. // constants will don't change
  139. const int contrastplus = 2; // the number of the pushbutton contrastplus pin
  140. const int contrastminus = 3; // the number of the pushbutton contrastminus pin
  141. // variables will change:
  142. int contrastplusState = 0; // variable for reading the pushbutton contrastplus
  143. int contrastminusState = 0; // variable for reading the pushbutton contrastminus
  144. int contrast_value; // contrast LCD value
  145. #define long_buffer 128
  146. #define inicio_trama '@'
  147. #define fin_trama '#'
  148. #define BOUNCE_DURATION 50
  149. volatile unsigned long bounceTime=0;
  150. char buffer[long_buffer+1]; // Allocate some space for the string
  151. char inChar=-1; // Where to store the character read
  152. byte index = 0; // Index into array; where to store the character
  153. char Time_str[10]={"00:00"};
  154. char Rain_time_str[10]={0,0,0,0,0,0,0,0,0,0};
  155. char Thunder_time_str[10]={0,0,0,0,0,0,0,0,0,0};
  156. char dist_to_spawn_str[10]={0,0,0,0,0,0,0,0,0,0};
  157. char PosX_str[8]={"0.000"};
  158. char PosY_str[8]={"0.000"};
  159. char PosZ_str[8]={"0.000"};
  160. char Hour_str[3]={0,0,0};
  161. char Minute_str[3]={0,0,0};
  162. char Day_str[3]={0,0,0};
  163. char Month_str[3]={0,0,0};
  164. char Year_str[5]={0,0,0,0,0};
  165. char Thundering_str=0x00;
  166. char Raining_str=0x00;
  167. char World_name[16]={"Minestation 1.0"};
  168. double Time=0;
  169. double Rain_time=0;
  170. double Thunder_time=0;
  171. short Thundering=0;
  172. short Raining=0;
  173. short Sun=0;
  174. short Moon=0;
  175. //float PosX=0.0;
  176. //float PosY=0.0;
  177. //float PosZ=0.0;
  178. float dist_to_spawn=0.0;
  179. int Hour=0;
  180. int Minute=0;
  181. int Day=1;
  182. int Month=1;
  183. int Year=0;
  184. int modo=0;
  185. int stringLen=15;
  186. int PosXSun=64;
  187. int PosYSun=15;
  188. int hourTmp;
  189. int minuteTmp;
  190. int dayTmp;
  191. int levelLight=5;
  192. int inByte;
  193. /*************************************************************/
  194. /* Function prototypes */
  195. /*************************************************************/
  196. void sendCMD(byte);
  197. void sendData(byte);
  198. void shiftBits(byte);
  199. void lcd_init();
  200. void draw_color_bar();
  201. void lcd_clear(uint16_t, byte, byte, byte, byte);
  202. void LCDPutStr(char*, int, int, int, int, int);
  203. void LCDPutChar(char, int, int, int, int, int);
  204. void LCDSetLine(int, int, int, int, int);
  205. void LCDSetRect(int, int, int, int, unsigned char fill, int);
  206. void LCDSetCircle(int, int, int, int);
  207. void LCDSetPixel(byte, byte, int);
  208. void LCDSetXY(byte, byte);
  209. void calculatePositionSun();
  210. void drawStormIcon(byte,byte);
  211. void drawRainIcon(byte, byte);
  212. void calculateTime(long);
  213. void drawCloud1(int,int);
  214. void drawCloud2(int,int);
  215. void drawSunMoon(int,int,int);
  216. void calculatePosSunMoon();
  217. void putBackground();
  218. /*************************************************************/
  219. /* Main Code Start here */
  220. /*************************************************************/
  221. void setup()
  222. {
  223. contrast_value=56;
  224. // initialize the pushbutton pins as inputs:
  225. pinMode(contrastplus, INPUT);
  226. pinMode(contrastminus, INPUT);
  227. DDRB=0x2F;
  228. DDRB=0x2F;
  229. // DDRD |= B01111100; // Set SPI pins as output
  230. // PORTD |= B01111100; // Set SPI pins HIGH
  231. Serial.begin(9600);
  232. Serial.write("Minestation Arduino v0.0.1");
  233. lcd_init();
  234. delay(500);
  235. lcd_contrast(contrast_value);
  236. attachInterrupt(0, contrastPlus, RISING);
  237. attachInterrupt(1, contrastMinus, RISING);
  238. Timer1.initialize(100000);
  239. draw_color_bar();
  240. delay(500);
  241. // lcd_clear(BLACK,0,0,131,131);
  242. /*
  243. LCDPutStr("Probando...", 5, 40, LARGE, YELLOW, BLACK);
  244. LCDPutStr("132X132", 20, 40, LARGE, CYAN, BLACK);
  245. LCDPutStr("Color Graphic LCD", 37, 17, SMALL, CYAN, BLACK);
  246. LCDPutStr("WWW.GRAVITECH.US", 50, 2, LARGE, RED, WHITE);
  247. LCDPutStr("SMALL GREEN", 70, 37, SMALL, GREEN, BLACK);
  248. LCDPutStr("MEDIUM BLUE", 81, 25, MEDIUM, BLUE, BLACK);
  249. LCDPutStr("LARGE PINK", 90, 27, LARGE, PINK, BLACK);
  250. LCDPutStr("MEDIUM MAGENTA", 107, 12, MEDIUM, MAGENTA, BLACK);
  251. LCDPutStr("SMALL ORANGE", 119, 30, SMALL, ORANGE, BLACK);
  252. delay(500);
  253. lcd_clear(BLUE,0,0,131,131);
  254. LCDSetLine(120, 10, 120, 50, YELLOW); // Draw Line Create Rectangle
  255. LCDSetLine(120, 50, 80, 50, YELLOW);
  256. LCDSetLine(80, 50, 80, 10, YELLOW);
  257. LCDSetLine(80, 10, 120, 10, YELLOW);
  258. LCDSetLine(120, 85, 80, 105, YELLOW); // Draw Line Create X
  259. LCDSetLine(80, 85, 120, 105, YELLOW);
  260. LCDSetCircle(62, 65, 20, RED); // Draw Circle
  261. LCDSetRect(5, 5, 125, 125, NOFILL, BLUE); // Draw box with no fill
  262. LCDSetRect(10, 10, 40, 40, FILL, PINK); // Draw box with fill
  263. LCDSetRect(10, 90, 40, 120, FILL, GREEN);
  264. delay(2000);
  265. lcd_clear(BLUE,0,0,131,131);
  266. delay(2000);*/
  267. lcd_clear(BLACK,0,0,131,131);
  268. lcd_clear(WHITE,116,0,131,131);
  269. LCDSetLine(0, 65,115, 65, WHITE); // Vertical division screen
  270. LCDSetLine(0, 66,115, 66, WHITE);
  271. LCDSetLine(17,65,17, 131, WHITE); // Clock division
  272. LCDSetLine(18,65,18, 131, WHITE);
  273. LCDSetLine(37,65,37, 131, WHITE); // Date division
  274. LCDSetLine(38,65,38, 131, WHITE);
  275. // Draw Atrezzo clock
  276. LCDSetCircle(8, 77, 7, GREEN); // Draw Circle
  277. LCDSetCircle(8, 77, 6, GREEN);
  278. LCDSetLine(8, 77, 5, 77, GREEN); // Draw hands clock
  279. LCDSetLine(8, 78, 5, 78, GREEN);
  280. LCDSetLine(8, 77, 9, 80, GREEN);
  281. LCDSetLine(8, 78, 9, 81, GREEN);
  282. //Draw Atrezzo calendar
  283. LCDSetRect(34, 69, 20, 86, NOFILL, RED); // Draw box
  284. LCDSetRect(35, 70, 21, 87, NOFILL, RED); // Draw box
  285. LCDSetPixel(35,87,BLACK);
  286. LCDSetPixel(20,69,BLACK);
  287. LCDSetLine(19, 75, 23, 75, RED);
  288. LCDSetLine(19, 74, 23, 74, RED);
  289. LCDSetLine(19, 80, 23, 80, RED);
  290. LCDSetLine(19, 81, 23, 81, RED);
  291. LCDSetLine(73,65,73, 131, WHITE); // Position division
  292. LCDSetLine(74,65,74, 131, WHITE);
  293. LCDSetLine(0,130,130, 130, WHITE); // Date division
  294. LCDSetLine(0,129,130,129, WHITE);
  295. putBackground();
  296. }
  297. void loop()
  298. {
  299. int px,py;
  300. int dd,ee;
  301. char str_tmp[16];
  302. int xxx,yyy;
  303. //Put World Name centered
  304. px=(132-(stringLen*8))/2;
  305. lcd_clear(WHITE,116,0,131,131);
  306. LCDPutStr(World_name, 116, px, LARGE, BLACK, WHITE);
  307. //Put Time
  308. if (Hour==24) Hour=0;
  309. sprintf(str_tmp,"%02d:%02d",Hour,Minute);
  310. LCDPutStr(str_tmp, 5, 95, SMALL,WHITE,BLACK);
  311. //Put Date
  312. sprintf(str_tmp,"%02d", Day);
  313. LCDPutStr(str_tmp, 25,73,SMALL,RED,BLACK);
  314. sprintf(str_tmp,"%02d/%02d", Month,Year);
  315. LCDPutStr(str_tmp, 25,95,SMALL,WHITE,BLACK);
  316. //Put coordenates
  317. LCDPutStr("X: ", 43, 73, SMALL, WHITE, BLACK);
  318. LCDPutStr(PosX_str, 43, 86, SMALL, WHITE, BLACK);
  319. LCDPutStr("Y: ", 53, 73, SMALL, WHITE, BLACK);
  320. LCDPutStr(PosY_str, 53, 86, SMALL, WHITE, BLACK);
  321. LCDPutStr("Z: ", 63, 73, SMALL, WHITE, BLACK);
  322. LCDPutStr(PosZ_str, 63, 86, SMALL, WHITE, BLACK); // LCDPutStr("6x8 How'r'u?", 24, 1, SMALL, GREEN, BLACK);
  323. xxx=PosXSun;
  324. yyy=PosYSun;
  325. calculatePosSunMoon();
  326. if ((xxx!=PosXSun) | (yyy!=PosYSun)){
  327. if ((Hour<21) & (Hour>6)) drawSunMoon(PosXSun,PosYSun,YELLOW);
  328. else drawSunMoon(PosXSun,PosYSun,WHITE);
  329. }
  330. // drawCloud1(-3,12);
  331. // drawCloud2(23,35);
  332. drawStormIcon(68,77);
  333. if (Raining==1) {
  334. lcd_clear(BLACK,96,68,110,83);
  335. drawRainIcon(68,96);
  336. }
  337. else {
  338. lcd_clear(BLACK,96,68,110,83);
  339. lcd_clear(YELLOW,99,71,109,81);
  340. }
  341. //Put Rain time
  342. calculateTime(Rain_time);
  343. if(dayTmp>0) sprintf(str_tmp,"%d days",dayTmp);
  344. else {
  345. if (hourTmp==24) hourTmp=0;
  346. sprintf(str_tmp,"%02d:%02d ",hourTmp,minuteTmp);
  347. }
  348. LCDPutStr(str_tmp, 102, 86, SMALL,WHITE,BLACK);
  349. //Put thunder time
  350. calculateTime(Thunder_time);
  351. if(dayTmp>0) sprintf(str_tmp,"%d days",dayTmp);
  352. else {
  353. if (hourTmp==24) hourTmp=0;
  354. sprintf(str_tmp,"%02d:%02d ",hourTmp,minuteTmp);
  355. }
  356. if(Raining==1)
  357. LCDPutStr(str_tmp, 82, 86, SMALL,WHITE,BLACK);
  358. else
  359. LCDPutStr(" Clear ", 82, 86, SMALL,WHITE,BLACK);
  360. inByte=Serial.read();
  361. if(inByte=='@'){
  362. recibe_trama();
  363. command_process();
  364. }
  365. }
  366. /*************************************************************/
  367. /* Function definitions */
  368. /*************************************************************/
  369. void putBackground(){
  370. lcd_clear(0xF30,0,0,114,64);
  371. bitmap(1,54,0); //Put world
  372. }
  373. void calculatePositionSun(){
  374. PosXSun=0;
  375. PosYSun=0;
  376. }
  377. void Inicia_buffer(){
  378. memset(buffer, '\0', 128);
  379. }
  380. void contrastPlus(){
  381. long dd,ddd;
  382. static long lasttime;
  383. if (millis()<lasttime) lasttime=millis();
  384. if((lasttime+BOUNCE_DURATION)>millis()) return;
  385. lasttime=millis();
  386. contrast_value++;
  387. lcd_contrast(contrast_value);
  388. }
  389. void contrastMinus(){
  390. long dd,ddd;
  391. static long lasttime;
  392. if (millis()<lasttime) lasttime=millis();
  393. if((lasttime+BOUNCE_DURATION)>millis()) return;
  394. lasttime=millis();
  395. contrast_value--;
  396. lcd_contrast(contrast_value);
  397. }
  398. void drawSunMoon(int pX, int pY,int color){
  399. int backColor=0xF30;
  400. switch (levelLight){
  401. case 0:
  402. backColor=0xF30;
  403. break;
  404. case 1:
  405. backColor=0xE20;
  406. break;
  407. case 2:
  408. backColor=0xD10;
  409. break;
  410. case 3:
  411. backColor=0xC00;
  412. break;
  413. case 4:
  414. backColor=0xB00;
  415. break;
  416. case 5:
  417. backColor=0xA00;
  418. break;
  419. }
  420. lcd_clear(backColor,0,0,53,64);
  421. if (pX<55) LCDSetRect(pY, pX, pY+10, pX+10, FILL, color); // Draw sun
  422. else LCDSetRect(pY, pX, pY+10, pX+64-pX, FILL, color);
  423. }
  424. void drawCloud1(int pX,int pY){
  425. // Part white in cloud1
  426. unsigned char linW [64] PROGMEM ={ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9,
  427. 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
  428. //Part grey in cloud1
  429. unsigned char linG [64] PROGMEM ={ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7,
  430. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8};
  431. byte fin=32;
  432. if((pX+32)>64) fin=64-pX;
  433. for (int o=0 ; o<fin ; o++){
  434. LCDSetLine(pY+linW[o],pX,pY+linW[o+32], pX, WHITE);
  435. LCDSetLine(pY+linG[o],pX,pY+linG[o+32], pX, GREY);
  436. if(o==10){
  437. LCDSetLine(pY+7,pX,pY+9, pX, WHITE);
  438. LCDSetPixel(pY+6,pX,GREY);
  439. }
  440. if(o==11){
  441. LCDSetLine(pY+8,pX,pY+9, pX, WHITE);
  442. LCDSetLine(pY+6,pX,pY+7, pX, GREY);
  443. }
  444. if(o==12){
  445. LCDSetPixel(pY+9,pX,WHITE);
  446. LCDSetLine(pY+7,pX,pY+8, pX, GREY);
  447. }
  448. pX++;
  449. }
  450. }
  451. void drawCloud2(int pX,int pY){
  452. // Part white in cloud1
  453. unsigned char linW [88] PROGMEM ={ 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
  454. 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15};
  455. //Part grey in cloud1
  456. unsigned char linG [88] PROGMEM ={ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,
  457. 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14};
  458. byte fin=44;
  459. if((pX+44)>64) fin=64-pX;
  460. for (int o=0 ; o<fin ; o++){
  461. LCDSetLine(pY+linW[o],pX,pY+linW[o+44], pX, WHITE);
  462. LCDSetLine(pY+linG[o],pX,pY+linG[o+44], pX, GREY);
  463. if(o==24){
  464. LCDSetPixel(pY+2,pX,WHITE);
  465. LCDSetPixel(pY+1,pX,GREY);
  466. }
  467. if(o==25){
  468. LCDSetLine(pY+2,pX,pY+3, pX, WHITE);
  469. LCDSetLine(pY+0,pX,pY+1, pX, GREY);
  470. }
  471. if(o==26){
  472. LCDSetLine(pY+2,pX,pY+4, pX, WHITE);
  473. LCDSetLine(pY+0,pX,pY+1, pX, GREY);
  474. }
  475. if(o==27){
  476. LCDSetLine(pY+2,pX,pY+5, pX, WHITE);
  477. LCDSetLine(pY+0,pX,pY+1, pX, GREY);
  478. }
  479. if(o==28){
  480. LCDSetLine(pY+2,pX,pY+6, pX, WHITE);
  481. LCDSetLine(pY+0,pX,pY+1, pX, GREY);
  482. }
  483. if(o==29){
  484. LCDSetLine(pY+2,pX,pY+7, pX, WHITE);
  485. LCDSetLine(pY+0,pX,pY+1, pX, GREY);
  486. }
  487. pX++;
  488. }
  489. }
  490. void calculatePosSunMoon(){
  491. int www;
  492. www=(Hour*60)+Minute;
  493. //Sunshine
  494. if ((www>420) & (www<480)) {
  495. PosXSun=((www-420)/6)-10;
  496. PosYSun=22-((www-420)/8);
  497. if (levelLight!=5-((www-420)/12)){
  498. levelLight=5-((www-420)/12);
  499. putBackground();
  500. }
  501. }
  502. //sunrising
  503. else if ((www>1200) & (www<1260)) {
  504. PosXSun=54+((www-1200)/6);
  505. PosYSun=15+((www-1200)/8);
  506. if (((www-1200)/12)!=levelLight){
  507. levelLight=((www-1200)/12);
  508. putBackground();
  509. }
  510. }
  511. else if ((www>480) & (www<1200)) {
  512. PosXSun=(www-480)/13;
  513. PosYSun=15;
  514. if (levelLight!=0){
  515. levelLight=0;
  516. putBackground();
  517. }
  518. }
  519. //Moon down
  520. else if ((www>360)&(www<=420)){
  521. PosXSun=54+((www-360)/6);
  522. PosYSun=15+((www-360)/8);
  523. }
  524. //Moon up
  525. else if ((www>=1260)&(www<1320)){
  526. PosXSun=((www-1260)/6)-10;
  527. PosYSun=22-((www-1260)/8);
  528. if (levelLight<5){
  529. levelLight=5;
  530. putBackground();
  531. }
  532. }
  533. else if ((www>=1320)&(www<=1440)){
  534. PosXSun=((www-1320)/11);
  535. PosYSun=15;
  536. }
  537. else if ((www>=0)&(www<=360)){
  538. PosXSun=11+(www/11);
  539. PosYSun=15;
  540. }
  541. }
  542. void drawStormIcon(byte pX,byte pY){
  543. LCDSetLine(0+pY,7+pX,7+pY,14+pX, YELLOW);
  544. LCDSetLine(7+pY,14+pX,4+pY,3+pX,YELLOW);
  545. LCDSetLine(4+pY,3+pX,15+pY,10+pX,YELLOW);
  546. LCDSetLine(15+pY,10+pX,13+pY,6+pX,YELLOW);
  547. LCDSetLine(15+pY,10+pX,11+pY,10+pX,YELLOW);
  548. }
  549. void drawRainIcon(byte pX, byte pY){
  550. LCDSetLine(2+pY,3+pX,4+pY,3+pX,BLUE);
  551. LCDSetLine(3+pY,2+pX,3+pY,4+pX,BLUE);
  552. LCDSetRect(2+pY,12+pX,3+pY,13+pX, NOFILL, BLUE); // Draw box
  553. LCDSetRect(3+pY,9+pX,4+pY,10+pX, NOFILL, BLUE); // Draw box
  554. LCDSetRect(4+pY,11+pX,5+pY,12+pX, NOFILL, BLUE); // Draw box
  555. LCDSetRect(6+pY,10+pX,7+pY,11+pX, NOFILL, CYAN); // Draw box
  556. LCDSetRect(5+pY,13+pX,6+pY,14+pX, NOFILL, CYAN); // Draw box
  557. LCDSetRect(8+pY,5+pX,9+pY,6+pX, NOFILL, CYAN2); // Draw box
  558. LCDSetRect(9+pY,4+pX,10+pY,5+pX, NOFILL, CYAN2); // Draw box
  559. LCDSetRect(9+pY,1+pX,10+pY,2+pX, NOFILL, CYAN2); // Draw box
  560. LCDSetRect(10+pY,2+pX,11+pY,3+pX, NOFILL, CYAN2); // Draw box
  561. LCDSetRect(11+pY,5+pX,12+pY,6+pX, NOFILL, CYAN); // Draw box
  562. LCDSetRect(12+pY,3+pX,13+pY,4+pX, NOFILL, CYAN); // Draw box
  563. LCDSetRect(12+pY,6+pX,13+pY,7+pX, NOFILL, CYAN); // Draw box
  564. LCDSetRect(13+pY,2+pX,14+pY,3+pX, NOFILL, CYAN); // Draw box
  565. }
  566. void calculateTime(long ttt){
  567. hourTmp=0;
  568. minuteTmp=0;
  569. dayTmp=0;
  570. minuteTmp=ttt/16.6666667;
  571. if(minuteTmp>1440) {
  572. dayTmp=minuteTmp/1440;
  573. minuteTmp=0;
  574. }
  575. else {
  576. minuteTmp+=Minute;
  577. if (minuteTmp>59) {
  578. hourTmp+=(minuteTmp/60);
  579. minuteTmp=minuteTmp%60;
  580. }
  581. hourTmp+=Hour;
  582. if (hourTmp>24){
  583. dayTmp+=hourTmp/24;
  584. }
  585. }
  586. }
  587. void recibe_trama(){
  588. /* byte inByte = '\0';
  589. while(inByte != inicio_trama) {
  590. while(!Serial.available()); // wait for input
  591. inByte = Serial.read(); // Wait for the start of the message
  592. }*/
  593. detachInterrupt(0); //Save from resets by overflow
  594. detachInterrupt(1); //Save from resets by overflow
  595. Inicia_buffer();
  596. index=0;
  597. do{
  598. while(!Serial.available()); // wait for input
  599. buffer[index] = Serial.read(); // get it
  600. // Serial.print(buffer[index]);
  601. if (buffer [index] == fin_trama) break;
  602. } while (++index < long_buffer);
  603. buffer[index] = 0; // null terminate the string*/
  604. //Restore external interrupts
  605. attachInterrupt(0, contrastPlus, RISING);
  606. attachInterrupt(1, contrastMinus, RISING);
  607. }
  608. ///////////////////////////////////////
  609. // Limpiar variables de string
  610. ///////////////////////////////////////
  611. void limpia_strings(){
  612. int f;
  613. for(f=0;f<16;f++){
  614. if (f<3){
  615. Hour_str[f]=0x00;
  616. Minute_str[f]=0x00;
  617. Day_str[f]=0x00;
  618. Month_str[f]=0x00;
  619. }
  620. if (f<5) Year_str[f]=0x00;
  621. if (f<8){
  622. PosX_str[f]=0x00;
  623. PosY_str[f]=0x00;
  624. PosZ_str[f]=0x00;
  625. }
  626. if (f<10){
  627. dist_to_spawn_str[f]=0x00;
  628. Time_str[f]=0x00;
  629. Rain_time_str[f]=0x00;
  630. Thunder_time_str[f]=0x00;
  631. }
  632. World_name[f]=0x00;
  633. }
  634. }
  635. /***************************************************************
  636. ** Parser del Buffer
  637. **
  638. ** String data format
  639. **
  640. ** @ //Start character
  641. ** int <time>
  642. ** int <min>
  643. ** int <hour>
  644. ** int <day>
  645. ** int <month>
  646. ** int <year>
  647. ** bool <sun?>
  648. ** bool <moon?>
  649. ** int <raining time left>
  650. ** int <thundering time left>
  651. ** bool <raining?>
  652. ** bool <thundering?>
  653. ** float <pos_x>
  654. ** float <pos_y>
  655. ** float <pos_z>
  656. ** float <distance to spawn from player>
  657. ** char* <name of world>
  658. ** # //End character
  659. **
  660. **
  661. ** Data string sample:
  662. ** @1232144,55,21,18,9,1974,1,0,12500,20000,0,0,12.6584,24.6854,-2.2359,145875,Twin Peaks#
  663. **
  664. ****************************************************************/
  665. void command_process(){
  666. int i,j;
  667. limpia_strings(); //Limpiar todas las cadenas
  668. i=0;
  669. //Tiempo
  670. j=0;
  671. while (buffer[i]!=','){
  672. Time_str[j++]=buffer[i];
  673. i++;
  674. }
  675. Time=atol(Time_str);
  676. i++;
  677. //Minutos
  678. j=0;
  679. while (buffer[i]!=','){
  680. Minute_str[j++]=buffer[i];
  681. i++;
  682. }
  683. Minute=atoi(Minute_str);
  684. i++;
  685. //Horas
  686. j=0;
  687. while (buffer[i]!=','){
  688. Hour_str[j++]=buffer[i];
  689. i++;
  690. }
  691. Hour=atoi(Hour_str);
  692. i++;
  693. //Dia
  694. j=0;
  695. while (buffer[i]!=','){
  696. Day_str[j++]=buffer[i];
  697. i++;
  698. }
  699. Day=atoi(Day_str);
  700. i++;
  701. //Mes
  702. j=0;
  703. while (buffer[i]!=','){
  704. Month_str[j++]=buffer[i];
  705. i++;
  706. }
  707. Month=atoi(Month_str);
  708. i++ ;
  709. //A単o
  710. j=0;
  711. while (buffer[i]!=','){
  712. Year_str[j++]=buffer[i];
  713. i++;
  714. }
  715. Year=atoi(Year_str);
  716. i++;
  717. //Sun FLag
  718. if(buffer[i]=='1') Sun=1;
  719. else Sun=0;
  720. i+=2;
  721. //Moon FLag
  722. if(buffer[i]=='1') Moon=1;
  723. else Moon=0;
  724. i+=2;
  725. //Rain Time
  726. j=0;
  727. while (buffer[i]!=','){
  728. Rain_time_str[j++]=buffer[i];
  729. i++;
  730. }
  731. Rain_time=atol(Rain_time_str);
  732. i++;
  733. //Thundering Time
  734. j=0;
  735. while (buffer[i]!=','){
  736. Thunder_time_str[j++]=buffer[i];
  737. i++;
  738. }
  739. Thunder_time=atol(Thunder_time_str);
  740. i++;
  741. //Raining FLag
  742. if(buffer[i]=='1') Raining=1;
  743. else Raining=0;
  744. i+=2;
  745. //Thundering flag
  746. if(buffer[i]=='1') Thundering=1;
  747. else Thundering=0;
  748. i+=2;
  749. //PosX
  750. j=0;
  751. while (buffer[i]!=','){
  752. if (j<7) PosX_str[j++]=buffer[i];
  753. i++;
  754. }
  755. //PosX=atof(PosX_str);
  756. i++;
  757. //PosY
  758. j=0;
  759. while (buffer[i]!=','){
  760. if (j<7) PosY_str[j++]=buffer[i];
  761. i++;
  762. }
  763. //PosY=atof(PosY_str);
  764. i++;
  765. //PosZ
  766. j=0;
  767. while (buffer[i]!=','){
  768. if (j<7) PosZ_str[j++]=buffer[i];
  769. i++;
  770. }
  771. //PosZ=atof(PosZ_str);
  772. i++;
  773. //Distance to Spawn
  774. j=0;
  775. while (buffer[i]!=','){
  776. dist_to_spawn_str[j++]=buffer[i];
  777. i++;
  778. }
  779. dist_to_spawn=atof(dist_to_spawn_str);
  780. i++;
  781. //World Name
  782. j=0;
  783. stringLen=0;
  784. while (buffer[i]!='\0'){
  785. World_name[j++]=buffer[i];
  786. i++;
  787. stringLen++;
  788. }
  789. Inicia_buffer(); // Borro buffer.
  790. }
  791. /**************************************/
  792. /* Change LCD contrast */
  793. /**************************************/
  794. void lcd_contrast(int value){
  795. sendCMD(SETCON); // Set Contrast
  796. sendData(value);
  797. Serial.print("contraste:");
  798. Serial.println(value);
  799. delay(80);
  800. }
  801. /**************************************/
  802. /* Sending command */
  803. /**************************************/
  804. void sendCMD(byte data)
  805. {
  806. byte i;
  807. LCD_DATA(0); // set up first bit as command or data
  808. LCD_CS(0); // Enable device CS
  809. LCD_CLK(0); // Pull Clock LOW
  810. LCD_CLK(1); // Pul Clock HIGH
  811. if(data == 0x0){ // spi cannot transfer zero??
  812. LCD_DATA(0);
  813. for(i=0; i<8; i++){
  814. LCD_CLK(0); // Pull Clock LOW
  815. LCD_CLK(1);
  816. }
  817. }
  818. else{
  819. SPCR |=0x50; // Enable Hardware SPI
  820. SPSR |= 0x1;
  821. SPDR = data; // send data
  822. while(!(SPSR & 0x80)); // wait until send complete
  823. }
  824. SPCR &=~0x50; // Disable Hardware SPI, this releases the SPI pins
  825. // for general IO use. which is used to send the 1'st
  826. LCD_CS(1); // disable device CS // bit out
  827. /* CS1
  828. CLK0
  829. CS0
  830. SDA0
  831. CLK1
  832. CLK0
  833. shiftBits(data);
  834. CLK0
  835. CS1*/
  836. }
  837. /**************************************/
  838. /* Sending data */
  839. /**************************************/
  840. void sendData(byte data) {
  841. byte i;
  842. LCD_DATA(1); // set up first bit as command or data
  843. LCD_CS(0); // Enable device CS
  844. LCD_CLK(0); // Pull Clock LOW
  845. LCD_CLK(1); // Pul Clock HIGH
  846. if(data == 0x0){ // spi cannot transfer zero??
  847. LCD_DATA(0);
  848. for(i=0; i<8; i++){
  849. LCD_CLK(0); // Pull Clock LOW
  850. LCD_CLK(1);
  851. }
  852. }
  853. else{
  854. SPCR |=0x50; // Enable Hardware SPI
  855. SPSR |= 0x1;
  856. SPDR = data; // send data
  857. while(!(SPSR & 0x80)); // wait until send complete
  858. }
  859. SPCR &=~0x50; // Disable Hardware SPI, this releases the SPI pins
  860. // for general IO use. which is used to send the 1'st
  861. LCD_CS(1); // disable device CS // bit out
  862. /* CS1
  863. CLK0
  864. CS0
  865. SDA1
  866. CLK1
  867. CLK0
  868. shiftBits(data);
  869. CLK0
  870. CS1*/
  871. }
  872. /**************************************/
  873. /* Shifting SPI bit out */
  874. /**************************************/
  875. void shiftBits(byte data)
  876. {
  877. byte Bit;
  878. for (Bit = 0; Bit < 8; Bit++) // 8 Bit Write
  879. {
  880. CLK0 // Standby SCLK
  881. if((data&0x80)>>7)
  882. {
  883. SDA1
  884. }
  885. else
  886. {
  887. SDA0
  888. }
  889. CLK1 // Strobe signal bit
  890. data <<= 1; // Next bit data
  891. }
  892. }
  893. /**************************************/
  894. /* Initialize LCD */
  895. /**************************************/
  896. void lcd_init()
  897. {
  898. /* // Initial state
  899. CLK0
  900. CS1
  901. SDA1
  902. // Hardware Reset LCD
  903. RESET0
  904. delay(100);
  905. RESET1
  906. delay(100);*/
  907. LCD_CS(1);
  908. LCD_CLK(0);
  909. LCD_DATA(0);
  910. LCD_RESET(1);
  911. delay(50);
  912. LCD_RESET(0);
  913. delay(50);
  914. LCD_RESET(1);
  915. delay(50);
  916. LCD_CS(1);
  917. LCD_CLK(1);
  918. LCD_DATA(1);
  919. delay(10);
  920. // Sleep out (commmand 0x11)
  921. sendCMD(SLEEPOUT);
  922. // Inversion on (command 0x20)
  923. //sendCMD(INVON); // seems to be required for this controller
  924. sendCMD(INVOFF);
  925. // Color Interface Pixel Format (command 0x3A)
  926. sendCMD(COLMOD);
  927. sendData(0x03); // 0x03 = 12 bits-per-pixel
  928. // Memory access controler (command 0x36)
  929. sendCMD(MADCTL);
  930. sendData(0b11010110); //C8); // 0xC0 = mirror x and y, reverse rgb
  931. // Write contrast (command 0x25)
  932. sendCMD(SETCON);
  933. sendData(0x3C); // contrast 0x30
  934. delay(1000);
  935. // Display On (command 0x29)
  936. sendCMD(DISPON);
  937. }
  938. /**************************************/
  939. /* Draw a demo color bar */
  940. /**************************************/
  941. void draw_color_bar()
  942. {
  943. lcd_clear(RED,0,0,131,33);
  944. lcd_clear(GREEN,0,34,131,66);
  945. lcd_clear(BLUE,0,67,131,99);
  946. lcd_clear(WHITE,0,100,131,131);
  947. }
  948. /**************************************/
  949. /* Clear LCD from (x0,y0) to (x1,y1) */
  950. /**************************************/
  951. void lcd_clear(uint16_t color, byte x0, byte y0, byte x1, byte y1)
  952. {
  953. uint16_t xmin, xmax, ymin, ymax;
  954. uint16_t i;
  955. // best way to create a filled rectangle is to define a drawing box
  956. // and loop two pixels at a time
  957. // calculate the min and max for x and y directions
  958. xmin = (x0 <= x1) ? x0 : x1;
  959. xmax = (x0 > x1) ? x0 : x1;
  960. ymin = (y0 <= y1) ? y0 : y1;
  961. ymax = (y0 > y1) ? y0 : y1;
  962. // specify the controller drawing box according to those limits
  963. // Row address set (command 0x2B)
  964. sendCMD(PASET);
  965. sendData(xmin);
  966. sendData(xmax);
  967. // Column address set (command 0x2A)
  968. sendCMD(CASET);
  969. sendData(ymin);
  970. sendData(ymax);
  971. // WRITE MEMORY
  972. sendCMD(RAMWR);
  973. // loop on total number of pixels / 2
  974. for (i = 0; i < ((((xmax - xmin + 1) * (ymax - ymin + 1)) / 2) + 1); i++)
  975. {
  976. // use the color value to output three data bytes covering two pixels
  977. // For some reason, it has to send blue first then green and red
  978. sendData((color << 4) | ((color & 0xF0) >> 4));
  979. sendData(((color >> 4) & 0xF0) | (color & 0x0F));
  980. sendData((color & 0xF0) | (color >> 8));
  981. }
  982. }
  983. // *************************************************************************************************
  984. // LCDPutStr.c
  985. //
  986. // Draws a null-terminates character string at the specified (x,y) address, size and color
  987. //
  988. // Inputs: pString = pointer to character string to be displayed
  989. // x = row address (0 .. 131)
  990. // y = column address (0 .. 131)
  991. // Size = font pitch (SMALL, MEDIUM, LARGE)
  992. // fColor = 12-bit foreground color value rrrrggggbbbb
  993. // bColor = 12-bit background color value rrrrggggbbbb
  994. //
  995. //
  996. // Returns: nothing
  997. //
  998. // Notes: Here's an example to display "Hello World!" at address (20,20)
  999. //
  1000. // LCDPutChar("Hello World!", 20, 20, LARGE, WHITE, BLACK);
  1001. //
  1002. //
  1003. // Author: James P Lynch July 7, 2007
  1004. // *************************************************************************************************
  1005. void LCDPutStr(char *pString, int x, int y, int Size, int fColor, int bColor)
  1006. {
  1007. // loop until null-terminator is seen
  1008. while (*pString != 0x00)
  1009. {
  1010. // draw the character
  1011. LCDPutChar(*pString++, x, y, Size, fColor, bColor);
  1012. // advance the y position
  1013. if (Size == SMALL)
  1014. y = y + 6;
  1015. else if (Size == MEDIUM)
  1016. y = y + 8;
  1017. else
  1018. y = y + 8;
  1019. // bail out if y exceeds 131
  1020. if (y > 131) break;
  1021. }
  1022. }
  1023. // *****************************************************************************
  1024. // LCDPutChar.c
  1025. //
  1026. // Draws an ASCII character at the specified (x,y) address and color
  1027. //
  1028. // Inputs: c = character to be displayed
  1029. // x = row address (0 .. 131)
  1030. // y = column address (0 .. 131)
  1031. // size = font pitch (SMALL, MEDIUM, LARGE)
  1032. // fcolor = 12-bit foreground color value rrrrggggbbbb
  1033. // bcolor = 12-bit background color value rrrrggggbbbb
  1034. //
  1035. //
  1036. // Returns: nothing
  1037. //
  1038. //
  1039. // Notes: Here's an example to display "E" at address (20,20)
  1040. //
  1041. // LCDPutChar('E', 20, 20, MEDIUM, WHITE, BLACK);
  1042. //
  1043. // (27,20) (27,27)
  1044. // | |
  1045. // | |
  1046. // ^ V V
  1047. // : _ # # # # # # # 0x7F
  1048. // : _ _ # # _ _ _ # 0x31
  1049. // : _ _ # # _ # _ _ 0x34
  1050. // x _ _ # # # # _ _ 0x3C
  1051. // : _ _ # # _ # _ _ 0x34
  1052. // : _ _ # # _ _ _ # 0x31
  1053. // : _ # # # # # # # 0x7F
  1054. // : _ _ _ _ _ _ _ _ 0x00
  1055. //
  1056. // ------y------->
  1057. // ^ ^
  1058. // | |
  1059. // | |
  1060. // (20,20) (20,27)
  1061. //
  1062. //
  1063. // The most efficient way to display a character is to make use of the "wrap-around" feature
  1064. // of the Philips PCF8833 LCD controller chip.
  1065. //
  1066. // Assume that we position the character at (20, 20) that's a (row, col) specification.
  1067. // With the row and column address set commands, you can specify an 8x8 box for the SMALL and MEDIUM
  1068. // characters or a 16x8 box for the LARGE characters.
  1069. //
  1070. // WriteSpiCommand(PASET); // set the row drawing limits
  1071. // WriteSpiData(20); //
  1072. // WriteSpiData(27); // limit rows to (20, 27)
  1073. //
  1074. // WriteSpiCommand(CASET); // set the column drawing limits
  1075. // WriteSpiData(20); //
  1076. // WriteSpiData(27); // limit columns to (20,27)
  1077. //
  1078. // When the algorithm completes col 27, the column address wraps back to 20
  1079. // At the same time, the row address increases by one (this is done by the controller)
  1080. //
  1081. // We walk through each row, two pixels at a time. The purpose is to create three
  1082. // data bytes representing these two pixels in the following format (as specified by Philips
  1083. // for RGB 4 : 4 : 4 format (see page 62 of PCF8833 controller manual).
  1084. //
  1085. // Data for pixel 0: RRRRGGGGBBBB
  1086. // Data for Pixel 1: RRRRGGGGBBBB
  1087. //
  1088. // WriteSpiCommand(RAMWR); // start a memory write (96 data bytes to follow)
  1089. //
  1090. // WriteSpiData(RRRRGGGG); // first pixel, red and green data
  1091. // WriteSpiData(BBBBRRRR); // first pixel, blue data; second pixel, red data
  1092. // WriteSpiData(GGGGBBBB); // second pixel, green and blue data
  1093. // :
  1094. // and so on until all pixels displayed!
  1095. // :
  1096. // WriteSpiCommand(NOP); // this will terminate the RAMWR command
  1097. //
  1098. //
  1099. // Author: James P Lynch July 7, 2007
  1100. // *****************************************************************************
  1101. void LCDPutChar(char c, int x, int y, int size, int fColor, int bColor)
  1102. {
  1103. int i,j;
  1104. unsigned int nCols;
  1105. unsigned int nRows;
  1106. unsigned int nBytes;
  1107. unsigned char PixelRow;
  1108. unsigned char Mask;
  1109. unsigned int Word0;
  1110. unsigned int Word1;
  1111. unsigned char *pFont;
  1112. unsigned char *pChar;
  1113. unsigned char *FontTable[] = {(unsigned char *)FONT6x8,
  1114. (unsigned char *)FONT6x8,
  1115. //(unsigned char *)FONT8x8,
  1116. (unsigned char *)FONT8x16};
  1117. // get pointer to the beginning of the selected font table
  1118. pFont = (unsigned char *)FontTable[size];
  1119. /* get the nColumns, nRows and nBytes */
  1120. //nCols = *pFont;
  1121. nCols = pgm_read_byte(&*pFont); // Array Flash
  1122. //nRows = *(pFont + 1);
  1123. nRows = pgm_read_byte(&*(pFont + 1)); // Array Flash
  1124. //nBytes = *(pFont + 2);
  1125. nBytes = pgm_read_byte(&*(pFont + 2)); // Array Flash
  1126. /* get pointer to the last byte of the desired character */
  1127. //pChar = pFont + (nBytes * (c - 0x1F)) + nBytes - 1;
  1128. pChar = pFont + (nBytes * (c - 0x1F));
  1129. // Row address set (command 0x2B)
  1130. sendCMD(PASET);
  1131. sendData(x);
  1132. sendData(x + nRows - 1);
  1133. // Column address set (command 0x2A)
  1134. sendCMD(CASET);
  1135. sendData(y);
  1136. sendData(y + nCols - 1);
  1137. // WRITE MEMORY
  1138. sendCMD(RAMWR);
  1139. // loop on each row, working backwards from the bottom to the top
  1140. for (i = nRows - 1; i >= 0; i--)
  1141. {
  1142. /* copy pixel row from font table and then decrement row */
  1143. //PixelRow = pgm_read_byte(&*pChar--); // Array Flash
  1144. //PixelRow = *pChar--;
  1145. PixelRow = pgm_read_byte(&*pChar++); // Array Flash
  1146. // loop on each pixel in the row (left to right)
  1147. // Note: we do two pixels each loop
  1148. Mask = 0x80;
  1149. for (j = 0; j < nCols; j += 2)
  1150. {
  1151. // if pixel bit set, use foreground color; else use the background color
  1152. // now get the pixel color for two successive pixels
  1153. if ((PixelRow & Mask) == 0)
  1154. Word0 = bColor;
  1155. else
  1156. Word0 = fColor;
  1157. Mask = Mask >> 1;
  1158. if ((PixelRow & Mask) == 0)
  1159. Word1 = bColor;
  1160. else
  1161. Word1 = fColor;
  1162. Mask = Mask >> 1;
  1163. // use this information to output three data bytes
  1164. // For some reason, it has to send blue first then green and red
  1165. sendData((Word0 << 4) | ((Word0 & 0xF0) >> 4));
  1166. sendData(((Word0 >> 4) & 0xF0) | (Word1 & 0x0F));
  1167. sendData((Word1 & 0xF0) | (Word1 >> 8));
  1168. }
  1169. }
  1170. // terminate the Write Memory command
  1171. sendCMD(NOP);
  1172. }
  1173. // *************************************************************************************************
  1174. // LCDSetLine.c
  1175. //
  1176. // Draws a line in the specified color from (x0,y0) to (x1,y1)
  1177. //
  1178. // Inputs: x = row address (0 .. 131)
  1179. // y = column address (0 .. 131)
  1180. // color = 12-bit color value rrrrggggbbbb
  1181. // rrrr = 1111 full red
  1182. // :
  1183. // 0000 red is off
  1184. //
  1185. // gggg = 1111 full green
  1186. // :
  1187. // 0000 green is off
  1188. //
  1189. // bbbb = 1111 full blue
  1190. // :
  1191. // 0000 blue is off
  1192. //
  1193. // Returns: nothing
  1194. //
  1195. // Note: good write-up on this algorithm in Wikipedia (search for Bresenham's line algorithm)
  1196. // see lcd.h for some sample color settings
  1197. //
  1198. // Authors: Dr. Leonard McMillan, Associate Professor UNC
  1199. // Jack Bresenham IBM, Winthrop University (Father of this algorithm, 1962)
  1200. //
  1201. // Note: taken verbatim from Professor McMillan's presentation:
  1202. // http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
  1203. //
  1204. // *************************************************************************************************
  1205. void LCDSetLine(int x0, int y0, int x1, int y1, int color)
  1206. {
  1207. int dy = y1 - y0;
  1208. int dx = x1 - x0;
  1209. int stepx, stepy;
  1210. if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
  1211. if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
  1212. dy <<= 1; // dy is now 2*dy
  1213. dx <<= 1; // dx is now 2*dx
  1214. LCDSetPixel(x0, y0, color);
  1215. if (dx > dy)
  1216. {
  1217. int fraction = dy - (dx >> 1); // same as 2*dy - dx
  1218. while (x0 != x1)
  1219. {
  1220. if (fraction >= 0)
  1221. {
  1222. y0 += stepy;
  1223. fraction -= dx; // same as fraction -= 2*dx
  1224. }
  1225. x0 += stepx;
  1226. fraction += dy; // same as fraction -= 2*dy
  1227. LCDSetPixel(x0, y0, color);
  1228. }
  1229. }
  1230. else
  1231. {
  1232. int fraction = dx - (dy >> 1);
  1233. while (y0 != y1)
  1234. {
  1235. if (fraction >= 0)
  1236. {
  1237. x0 += stepx;
  1238. fraction -= dy;
  1239. }
  1240. y0 += stepy;
  1241. fraction += dx;
  1242. LCDSetPixel(x0, y0, color);
  1243. }
  1244. }
  1245. }
  1246. // *****************************************************************************************
  1247. // LCDSetRect.c
  1248. //
  1249. // Draws a rectangle in the specified color from (x1,y1) to (x2,y2)
  1250. // Rectangle can be filled with a color if desired
  1251. //
  1252. // Inputs: x = row address (0 .. 131)
  1253. // y = column address (0 .. 131)
  1254. // fill = 0=no fill, 1-fill entire rectangle
  1255. // color = 12-bit color value for lines rrrrggggbbbb
  1256. // rrrr = 1111 full red
  1257. // :
  1258. // 0000 red is off
  1259. //
  1260. // gggg = 1111 full green
  1261. // :
  1262. // 0000 green is off
  1263. //
  1264. // bbbb = 1111 full blue
  1265. // :
  1266. // 0000 blue is off
  1267. // Returns: nothing
  1268. //
  1269. // Notes:
  1270. //
  1271. // The best way to fill a rectangle is to take advantage of the "wrap-around" featute
  1272. // built into the Philips PCF8833 controller. By defining a drawing box, the memory can
  1273. // be simply filled by successive memory writes until all pixels have been illuminated.
  1274. //
  1275. // 1. Given the coordinates of two opposing corners (x0, y0) (x1, y1)
  1276. // calculate the minimums and maximums of the coordinates
  1277. //
  1278. // xmin = (x0 <= x1) ? x0 : x1;
  1279. // xmax = (x0 > x1) ? x0 : x1;
  1280. // ymin = (y0 <= y1) ? y0 : y1;
  1281. // ymax = (y0 > y1) ? y0 : y1;
  1282. //
  1283. // 2. Now set up the drawing box to be the desired rectangle
  1284. //
  1285. // WriteSpiCommand(PASET); // set the row boundaries
  1286. // WriteSpiData(xmin);
  1287. // WriteSpiData(xmax);
  1288. // WriteSpiCommand(CASET); // set the column boundaries
  1289. // WriteSpiData(ymin);
  1290. // WriteSpiData(ymax);
  1291. //
  1292. // 3. Calculate the number of pixels to be written divided by 2
  1293. //
  1294. // NumPixels = ((((xmax - xmin + 1) * (ymax - ymin + 1)) / 2) + 1)
  1295. //
  1296. // You may notice that I added one pixel to the formula.
  1297. // This covers the case where the number of pixels is odd and we
  1298. // would lose one pixel due to rounding error. In the case of
  1299. // odd pixels, the number of pixels is exact.
  1300. // in the case of even pixels, we have one more pixel than
  1301. // needed, but it cannot be displayed because it is outside
  1302. // the drawing box.
  1303. //
  1304. // We divide by 2 because two pixels are represented by three bytes.
  1305. // So we work through the rectangle two pixels at a time.
  1306. //
  1307. // 4. Now a simple memory write loop will fill the rectangle
  1308. //
  1309. // for (i = 0; i < ((((xmax - xmin + 1) * (ymax - ymin + 1)) / 2) + 1); i++) {
  1310. // WriteSpiData((color >> 4) & 0xFF);
  1311. // WriteSpiData(((color & 0xF) << 4) | ((color >> 8) & 0xF));
  1312. // WriteSpiData(color & 0xFF);
  1313. // }
  1314. //
  1315. // In the case of an unfilled rectangle, drawing four lines with the Bresenham line
  1316. // drawing algorithm is reasonably efficient.
  1317. //
  1318. // Author: James P Lynch July 7, 2007
  1319. // *****************************************************************************************
  1320. void LCDSetRect(int x0, int y0, int x1, int y1, unsigned char fill, int color)
  1321. {
  1322. int xmin, xmax, ymin, ymax;
  1323. int i;
  1324. // check if the rectangle is to be filled
  1325. if (fill == FILL)
  1326. {
  1327. // best way to create a filled rectangle is to define a drawing box
  1328. // and loop two pixels at a time
  1329. // calculate the min and max for x and y directions
  1330. xmin = (x0 <= x1) ? x0 : x1;
  1331. xmax = (x0 > x1) ? x0 : x1;
  1332. ymin = (y0 <= y1) ? y0 : y1;
  1333. ymax = (y0 > y1) ? y0 : y1;
  1334. // specify the controller drawing box according to those limits
  1335. // Row address set (command 0x2B)
  1336. sendCMD(PASET);
  1337. sendData(xmin);
  1338. sendData(xmax);
  1339. // Column address set (command 0x2A)
  1340. sendCMD(CASET);
  1341. sendData(ymin);
  1342. sendData(ymax);
  1343. // WRITE MEMORY
  1344. sendCMD(RAMWR);
  1345. // loop on total number of pixels / 2
  1346. for (i = 0; i < ((((xmax - xmin + 1) * (ymax - ymin + 1)) / 2) + 1); i++)
  1347. {
  1348. // use the color value to output three data bytes covering two pixels
  1349. // For some reason, it has to send blue first then green and red
  1350. sendData((color << 4) | ((color & 0xF0) >> 4));
  1351. sendData(((color >> 4) & 0xF0) | (color & 0x0F));
  1352. sendData((color & 0xF0) | (color >> 8));
  1353. }
  1354. }
  1355. else
  1356. {
  1357. // best way to draw un unfilled rectangle is to draw four lines
  1358. LCDSetLine(x0, y0, x1, y0, color);
  1359. LCDSetLine(x0, y1, x1, y1, color);
  1360. LCDSetLine(x0, y0, x0, y1, color);
  1361. LCDSetLine(x1, y0, x1, y1, color);
  1362. }
  1363. }
  1364. // *************************************************************************************
  1365. // LCDSetCircle.c
  1366. //
  1367. // Draws a line in the specified color at center (x0,y0) with radius
  1368. //
  1369. // Inputs: x0 = row address (0 .. 131)
  1370. // y0 = column address (0 .. 131)
  1371. // radius = radius in pixels
  1372. // color = 12-bit color value rrrrggggbbbb
  1373. //
  1374. // Returns: nothing
  1375. //
  1376. // Author: Jack Bresenham IBM, Winthrop University (Father of this algorithm, 1962)
  1377. //
  1378. // Note: taken verbatim Wikipedia article on Bresenham's line algorithm
  1379. // http://www.wikipedia.org
  1380. //
  1381. // *************************************************************************************
  1382. void LCDSetCircle(int x0, int y0, int radius, int color)
  1383. {
  1384. int f = 1 - radius;
  1385. int ddF_x = 0;
  1386. int ddF_y = -2 * radius;
  1387. int x = 0;
  1388. int y = radius;
  1389. LCDSetPixel(x0, y0 + radius, color);
  1390. LCDSetPixel(x0, y0 - radius, color);
  1391. LCDSetPixel(x0 + radius, y0, color);
  1392. LCDSetPixel(x0 - radius, y0, color);
  1393. while (x < y)
  1394. {
  1395. if (f >= 0)
  1396. {
  1397. y--;
  1398. ddF_y += 2;
  1399. f += ddF_y;
  1400. }
  1401. x++;
  1402. ddF_x += 2;
  1403. f += ddF_x + 1;
  1404. LCDSetPixel(x0 + x, y0 + y, color);
  1405. LCDSetPixel(x0 - x, y0 + y, color);
  1406. LCDSetPixel(x0 + x, y0 - y, color);
  1407. LCDSetPixel(x0 - x, y0 - y, color);
  1408. LCDSetPixel(x0 + y, y0 + x, color);
  1409. LCDSetPixel(x0 - y, y0 + x, color);
  1410. LCDSetPixel(x0 + y, y0 - x, color);
  1411. LCDSetPixel(x0 - y, y0 - x, color);
  1412. }
  1413. }
  1414. // *************************************************************************************
  1415. // LCDSetPixel.c
  1416. //
  1417. // Lights a single pixel in the specified color at the specified x and y addresses
  1418. //
  1419. // Inputs: x = row address (0 .. 131)
  1420. // y = column address (0 .. 131)
  1421. // color = 12-bit color value rrrrggggbbbb
  1422. // rrrr = 1111 full red
  1423. // :
  1424. // 0000 red is off
  1425. //
  1426. // gggg = 1111 full green
  1427. // :
  1428. // 0000 green is off
  1429. //
  1430. // bbbb = 1111 full blue
  1431. // :
  1432. // 0000 blue is off
  1433. //
  1434. // Returns: nothing
  1435. //
  1436. // Note: see lcd.h for some sample color settings
  1437. //
  1438. // Author: James P Lynch July 7, 2007
  1439. // Modified: Gravitech December 20, 2008
  1440. // *************************************************************************************
  1441. void LCDSetPixel(byte x, byte y, int color)
  1442. {
  1443. LCDSetXY(x, y);
  1444. sendCMD(RAMWR);
  1445. // For some reason, it has to send blue first then green and red
  1446. sendData((color << 4) | ((color & 0xF0) >> 4));
  1447. sendData(((color >> 4) & 0xF0));
  1448. sendCMD(NOP);
  1449. }
  1450. // *****************************************************************************
  1451. // LCDSetXY.c
  1452. //
  1453. // Sets the Row and Column addresses
  1454. //
  1455. // Inputs: x = row address (0 .. 131)
  1456. // y = column address (0 .. 131)
  1457. //
  1458. //
  1459. // Returns: nothing
  1460. //
  1461. // Author: James P Lynch July 7, 2007
  1462. // Modified: Gravitech December 20, 2008
  1463. // *****************************************************************************
  1464. void LCDSetXY(byte x, byte y)
  1465. {
  1466. // Row address set (command 0x2B)
  1467. sendCMD(PASET);
  1468. sendData(x);
  1469. sendData(x);
  1470. // Column address set (command 0x2A)
  1471. sendCMD(CASET);
  1472. sendData(y);
  1473. sendData(y);
  1474. }
  1475. void SendLcd_color(unsigned char color){
  1476. LCD_DATA(LCDData); // set up first bit as command or data
  1477. LCD_CLK(0); // Pull Clock LOW
  1478. LCD_CLK(1); // Pul Clock HIGH
  1479. LCD_CLK(0);
  1480. SPCR |=0x50; // Enable Hardware SPI
  1481. SPSR |=0x1;
  1482. SPDR = color; // send data
  1483. while(!(SPSR & 0x80)); // wait until send complete
  1484. // disable device CS
  1485. SPCR &=~0x50; // Disable Hardware SPI, this releases the SPI pins
  1486. LCD_CLK(0); // for general IO use. which is used to send the 1'st
  1487. // bit out
  1488. }
  1489. void LCDBitmap (unsigned char start_x, unsigned char start_y, unsigned char h_size, unsigned char v_size, unsigned char *bitmap_data)
  1490. {
  1491. int i;
  1492. unsigned char *pBitmap;
  1493. // specify the controller drawing box according to those limits
  1494. // Row address set (command 0x2B)
  1495. sendCMD(PASET);
  1496. sendData(start_x);
  1497. sendData( start_x+h_size-1);
  1498. // Column address set (command 0x2A)
  1499. sendCMD(CASET);
  1500. sendData(start_y);
  1501. sendData(start_y+v_size-1);
  1502. // WRITE MEMORY
  1503. sendCMD(RAMWR);
  1504. pBitmap = bitmap_data;
  1505. // loop on total number of pixels / 2
  1506. for (i = 0; i< (h_size*v_size)>>1 ; i++) {
  1507. unsigned char bitmap;
  1508. LCD_CS(0);
  1509. bitmap = pgm_read_byte(pBitmap++);
  1510. if (levelLight>0){
  1511. if ((bitmap & 0b00001111)>levelLight) bitmap=bitmap-levelLight;
  1512. else bitmap=bitmap&0b11110000;
  1513. if ((bitmap & 0b11110000)>(levelLight<<4)) bitmap=bitmap-(levelLight<<4);
  1514. else bitmap=bitmap & 0b00001111;
  1515. }
  1516. SendLcd_color(bitmap);
  1517. bitmap =pgm_read_byte(pBitmap++);
  1518. if (levelLight>0){
  1519. if ((bitmap & 0b00001111)>levelLight) bitmap=bitmap-levelLight;
  1520. else bitmap=bitmap&0b11110000;
  1521. if ((bitmap & 0b11110000)>(levelLight<<4)) bitmap=bitmap-(levelLight<<4);
  1522. else bitmap=bitmap & 0b00001111;
  1523. }
  1524. SendLcd_color(bitmap);
  1525. bitmap =pgm_read_byte(pBitmap++);
  1526. if (levelLight>0){
  1527. if ((bitmap & 0b00001111)>levelLight) bitmap=bitmap-levelLight;
  1528. else bitmap=bitmap&0b11110000;
  1529. if ((bitmap & 0b11110000)>(levelLight<<4)) bitmap=bitmap-(levelLight<<4);
  1530. else bitmap=bitmap & 0b00001111;
  1531. }
  1532. SendLcd_color(bitmap);
  1533. LCD_CS(1);
  1534. }
  1535. sendCMD(NOP);
  1536. }
  1537. void bitmap(int y,int x, char bmp){
  1538. unsigned char *pbitmap;
  1539. byte image_h, image_w;
  1540. switch (bmp){
  1541. case 0:
  1542. // pbitmap=barra;
  1543. pbitmap=image;
  1544. break;
  1545. case 1:
  1546. //pbitmap=lateralizquierdo;
  1547. break;
  1548. case 2:
  1549. //pbitmap=lateralderecho;
  1550. break;
  1551. }
  1552. image_w = pgm_read_byte(pbitmap+1);
  1553. image_h = pgm_read_byte(pbitmap+2);
  1554. LCDBitmap(x, y, image_w, image_h, pbitmap+5);
  1555. }