Paso 9: ¿Cómo trazar la línea?
Una vez que tenemos una función del pixel, podemos usar para trazar una línea definida por un inicio y punto final en x e y axis en la pantalla.
#include //Include Wire library for I2C communication#define HEIGHT 64 #define WIDTH 128 const int RST = 10; //Assign pin 10 for Reset int i; //Set variable i as integer static unsigned char array[1024]; //Buffer array void setup() { pin_init(); //Initialize pins initialize_OLED(); //Initialize screen memset(array, 0, sizeof(array)); //Initialize array with 0s line(0,63,0,31); //Draw line Flush(); //Send data } void loop() { } void pin_init(){ Serial.begin(9600); //Set baud for serial transmission pinMode(RST, OUTPUT); //Set RST as output } void initialize_OLED(){ Wire.begin(); //Initialize I2C interface digitalWrite(RST, LOW); //Set RST pin low delay(100); //Wait 100 ms digitalWrite(RST, HIGH); //Set RST pin high Wire.beginTransmission(0x3D); // Start communication with slave Wire.write(0x00); //Command stream Wire.write(0xAE); //Set display Off Wire.write(0xD5); //Set display clock divide ratio/oscillator frequency Wire.write(0x80); Wire.write(0xA8); //Set multiplex ratio Wire.write(0x3F); Wire.write(0xD3); //Set display offset Wire.write(0x00); Wire.write(0x40); //Set display start line Wire.write(0x8D); //Set charge pump Wire.write(0x14); //VCC generated by internal DC/DC circuit Wire.write(0xA1); //Set segment re-map Wire.write(0xC0); //Set COM output scan direction Wire.write(0xDA); //Set COM pins hardware configuration Wire.write(0x12); Wire.write(0x81); //Set contrast control Wire.write(0xCF); Wire.write(0xD9); //Set pre-changed period Wire.write(0xF1); Wire.write(0xDB); //Set VCOMH Deselected level Wire.write(0x40); Wire.write(0xA4); //Set entire display on/off Wire.write(0xA6); //Set normal/inverse display Wire.write(0x20); //Set memory address mode Wire.write(0x00); //Horizontal Wire.write(0xAF); //Set display on Wire.endTransmission(); //End communicaiton with slave } /*Bresenham's line drawing algorithm*/ void line(int x1, int x2, int y1, int y2){ int cx = x1; int cy = y1; int dx = x2-cx; int dy = y2-cy; if(dx<0){ dx = 0-dx; } if(dy<0){ dy = 0-dy; } int sx = 0; int sy = 0; if(cx(0-dy)){ err = err-dy; cx = cx+sx; } if(e2=WIDTH) || (y<0) || (y>=HEIGHT)){ //Check for boundaries return; } else{ array[x+(y/8)*WIDTH] |= _BV((y%8)); //Store pixel in array } } void Flush(){ Wire.beginTransmission(0x3D); //Start communication with slave Wire.write(0x00); //Command stream Wire.write(0x00); //Set lower column start address for page addressing mode Wire.write(0x10); //Set higher column start address for page addressing mode Wire.write(0x40); //Set display start line Wire.endTransmission(); //End communication with slave unsigned char twbrbackup = TWBR; //Two wire bit rate register TWBR = 12; //Set to 400 kHz for(unsigned short q=0; q<(WIDTH*HEIGHT/8); q++){ Wire.beginTransmission(0x3D); //Start communication with slave Wire.write(0x40); //Data stream for(unsigned char w=0; w<16; w++){ Wire.write(array[q]); //Transmit data to be displayed q++; } q--; Wire.endTransmission(); //End communication with slave } TWBR = twbrbackup; }
La función de línea se basa en el Algoritmo de Bresenham dibujo utilizado para dibujar líneas con píxeles. El siguiente pseudo código se utilizó para implementar el algoritmo en nuestro programa:
http://41j.com/blog/2012/09/bresenhams-line-drawin...
Este algoritmo básicamente rellena los píxeles entre (x 0, y0) y (x1, y1) por decidir qué pixeles deben girarse el siguiente basado en un valor de error. Consulte los siguientes enlaces para obtener más información sobre el algoritmo:
http://www.cs.Helsinki.fi/Group/Goa/mallinnus/line...
https://en.wikipedia.org/wiki/Bresenham%27s_line_a...