diff --git a/Inc/ssd1306.h b/Inc/ssd1306.h index 53a33a5..90b2af5 100644 --- a/Inc/ssd1306.h +++ b/Inc/ssd1306.h @@ -1,4 +1,4 @@ - +#include #include "stm32f4xx_hal.h" #include "fonts.h" @@ -49,6 +49,10 @@ #define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29 #define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A +#ifndef _swap_int16_t +#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } +#endif + // // Enum voor de kleuren van het scherm Black en White // @@ -84,5 +88,6 @@ void ssd1306_SetCursor(uint8_t x, uint8_t y); void ssd1306_WriteCommand(uint8_t command); void ssd1306_Scroll(void); void startscrollright(uint8_t start, uint8_t stop); +void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1); #endif diff --git a/Src/main.c b/Src/main.c index ab0d3d7..07bb92b 100644 --- a/Src/main.c +++ b/Src/main.c @@ -33,6 +33,7 @@ /* Includes ------------------------------------------------------------------*/ #include #include +#include #include "main.h" #include "stm32f4xx_hal.h" @@ -54,6 +55,29 @@ char UART_Buffer[32]; char text[32]; int i; +typedef struct { + float x; + float y; + float z; +} triPoint; + +triPoint vertices[8]; +triPoint lineVertices[8]; + +uint32_t angleX = 0; +uint32_t angleY = 0; +uint32_t angleZ = 0; + +struct _tStar +{ + unsigned char nX; + unsigned char nY; + unsigned char nStarType; +}; + +#define STARS_NUM 80 +struct _tStar aStars[STARS_NUM]; + /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ @@ -69,13 +93,92 @@ static void MX_USART1_UART_Init(void); /* USER CODE END PFP */ /* USER CODE BEGIN 0 */ +triPoint rotateX(triPoint startingPoint, uint16_t angle) { + triPoint computedPoint; + float rad = angle * 3.141592 / 180; + float cosa = cos(rad); + float sina = sin(rad); + computedPoint.x = startingPoint.x; + computedPoint.y = (startingPoint.y * cosa) - (startingPoint.z * sina); + computedPoint.z = (startingPoint.y * sina) + (startingPoint.z * cosa); + return computedPoint; +} + +triPoint rotateY(triPoint startingPoint, uint16_t angle) { + triPoint computedPoint; + + float rad = angle * 3.141592 / 180; + float cosa = cos(rad); + float sina = sin(rad); + computedPoint.y = startingPoint.y; + computedPoint.z = (startingPoint.z * cosa) - (startingPoint.x * sina); + computedPoint.x = (startingPoint.z * sina) + (startingPoint.x * cosa); + return computedPoint; +} + +triPoint rotateZ(triPoint startingPoint, uint16_t angle) { + triPoint computedPoint; + + float rad = angle * 3.141592 / 180; + float cosa = cos(rad); + float sina = sin(rad); + computedPoint.z = startingPoint.z; + computedPoint.x = (startingPoint.x * cosa) - (startingPoint.y * sina); + computedPoint.y = (startingPoint.x * sina) + (startingPoint.y * cosa); + return computedPoint; +} + +triPoint projectPoint(triPoint startingPoint, uint8_t win_width, uint8_t win_height, uint8_t fov, uint8_t viewer_distance) { + triPoint returnPoint; + float factor = fov/(viewer_distance + startingPoint.z); + returnPoint.x = startingPoint.x * factor + win_width/2; + returnPoint.y = -startingPoint.y * factor + win_height/2; + returnPoint.z = 1; + return returnPoint; +} /* USER CODE END 0 */ int main(void) { /* USER CODE BEGIN 1 */ + vertices[0].x = -1; + vertices[0].y = 1; + vertices[0].z = -1; + vertices[1].x = 1; + vertices[1].y = 1; + vertices[1].z = -1; + vertices[2].x = 1; + vertices[2].y = -1; + vertices[2].z = -1; + vertices[3].x = -1; + vertices[3].y = -1; + vertices[3].z = -1; + vertices[4].x = -1; + vertices[4].y = 1; + vertices[4].z = 1; + vertices[5].x = 1; + vertices[5].y = 1; + vertices[5].z = 1; + vertices[6].x = 1; + vertices[6].y = -1; + vertices[6].z = 1; + vertices[7].x = -1; + vertices[7].y = -1; + vertices[7].z = 1; + triPoint calcPoint, newPoint; + + unsigned char nStar = 0; + memset(aStars, 0, sizeof(aStars)); + + //Init + for(nStar = 0; nStar < STARS_NUM; nStar++) + { + aStars[nStar].nX = rand() % 128; + aStars[nStar].nY = rand() % 64; + aStars[nStar].nStarType = rand() % 3; + } /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ @@ -100,18 +203,24 @@ int main(void) ssd1306_DrawPixel(y, 20, White); } */ + //drawLine(1, 1, 20, 20); //ssd1306_UpdateScreen(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ + int zbr = 40; + int direction = 1; while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ + ssd1306_Fill(Black); + //ssd1306_UpdateScreen(); + /* int x, msg; - //HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6); //Toggle the state of pin PC9 + HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6); //Toggle the state of pin PC9 //DHT22_Read(htim6); @@ -127,16 +236,81 @@ int main(void) msg = rand() % 2 + 1; ssd1306_SetCursor(x, 53); ssd1306_WriteString((msg == 1) ? "GORDOS" : "LOL", Font_7x10, White); - -/* - for(int y = 0; y < 129; y++) { - ssd1306_DrawPixel(y, 63, White); - } */ + + for(nStar = 0; nStar < STARS_NUM; nStar++) { + //move star + switch(aStars[nStar].nStarType) { + case 0: //slow star + aStars[nStar].nX += 2; + break; + case 1: //medium star + aStars[nStar].nX += 3; + break; + case 2: //fast star + aStars[nStar].nX += 4; + break; + } + + if (aStars[nStar].nX >= 160) { + HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6); //Toggle the state of pin PC9 + aStars[nStar].nX = 0; + aStars[nStar].nY = rand() % 200; + aStars[nStar].nStarType = rand() % 3; + continue; + } + + //paint star + ssd1306_DrawPixel(aStars[nStar].nX, aStars[nStar].nY, White); + } +/* + ssd1306_SetCursor(zbr - 39, (sin(zbr) * 10) + 10); + ssd1306_WriteString("LOLGORDOS", Font_7x10, White); + + //ssd1306_SetCursor(zbr - 39, 53); + ssd1306_SetCursor(zbr - 39, (sin(zbr) * 10) + 43); + ssd1306_WriteString("DEMOSCENE", Font_7x10, White); +*/ + + if (direction == 1) { + zbr++; + } else { + zbr--; + } + + for (uint8_t i = 0; i<8; i++) { + calcPoint = rotateZ(vertices[i],angleZ++); + calcPoint = rotateY(calcPoint,angleY++); + calcPoint = rotateX(calcPoint,angleX++); + newPoint = projectPoint(calcPoint, 128, 64, zbr, 5); + lineVertices[i] = newPoint; + } + + drawLine(lineVertices[0].x,lineVertices[0].y,lineVertices[1].x,lineVertices[1].y); + drawLine(lineVertices[1].x,lineVertices[1].y,lineVertices[2].x,lineVertices[2].y); + drawLine(lineVertices[2].x,lineVertices[2].y,lineVertices[3].x,lineVertices[3].y); + drawLine(lineVertices[3].x,lineVertices[3].y,lineVertices[0].x,lineVertices[0].y); + drawLine(lineVertices[0].x,lineVertices[0].y,lineVertices[4].x,lineVertices[4].y); + drawLine(lineVertices[1].x,lineVertices[1].y,lineVertices[5].x,lineVertices[5].y); + drawLine(lineVertices[2].x,lineVertices[2].y,lineVertices[6].x,lineVertices[6].y); + drawLine(lineVertices[3].x,lineVertices[3].y,lineVertices[7].x,lineVertices[7].y); + drawLine(lineVertices[4].x,lineVertices[4].y,lineVertices[5].x,lineVertices[5].y); + drawLine(lineVertices[5].x,lineVertices[5].y,lineVertices[6].x,lineVertices[6].y); + drawLine(lineVertices[6].x,lineVertices[6].y,lineVertices[7].x,lineVertices[7].y); + drawLine(lineVertices[7].x,lineVertices[7].y,lineVertices[4].x,lineVertices[4].y); + ssd1306_UpdateScreen(); + HAL_Delay(25); + + if (zbr > 100) { + direction = 0; + } + + if (zbr < 40) { + direction = 1; + } } /* USER CODE END 3 */ - } /** System Clock Configuration diff --git a/Src/ssd1306.c b/Src/ssd1306.c index 74ad1c6..a9090fa 100644 --- a/Src/ssd1306.c +++ b/Src/ssd1306.c @@ -1,7 +1,6 @@ #include"ssd1306.h" -// Databuffer voor het scherm -//static uint8_t SSD1306_Buffer[SSD1306_WIDTH * SSD1306_HEIGHT / 8]; + static uint8_t SSD1306_Buffer[SSD1306_HEIGHT * SSD1306_WIDTH / 8]; // Een scherm-object om lokaal in te werken @@ -18,19 +17,78 @@ void startscrollright(uint8_t start, uint8_t stop){ ssd1306_WriteCommand(SSD1306_ACTIVATE_SCROLL); } -void ssd1306_Scroll() -{ - static uint32_t end = SSD1306_WIDTH * 8; - uint8_t bit_antigo = 0; - - for(uint32_t addr = 0; addr < end; addr++) { - if (addr > 0x79) { - bit_antigo = SSD1306_Buffer[addr] & 0x01; - } - SSD1306_Buffer[addr] >>= 1; - bit_antigo <<= 7; - SSD1306_Buffer[addr - SSD1306_WIDTH] |= bit_antigo; +void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1) +{ + int16_t steep = abs(y1 - y0) > abs(x1 - x0); + if (steep) { + _swap_int16_t(x0, y0); + _swap_int16_t(x1, y1); + } + + if (x0 > x1) { + _swap_int16_t(x0, x1); + _swap_int16_t(y0, y1); + } + + int16_t dx, dy; + dx = x1 - x0; + dy = abs(y1 - y0); + + int16_t err = dx / 2; + int16_t ystep; + + if (y0 < y1) { + ystep = 1; + } else { + ystep = -1; + } + + for (; x0<=x1; x0++) { + if (steep) { + ssd1306_DrawPixel(y0, x0, White); + } else { + ssd1306_DrawPixel(x0, y0, White); + } + err -= dy; + if (err < 0) { + y0 += ystep; + err += dx; + } + } +} + +/** + * [ssd1306_ScrollUp scrolls the whole LCD buffer up] + * @param pixels [How many pixels to scroll up] + * @param delay [Delay between refresh] + */ +void ssd1306_ScrollUp(unsigned int pixels, unsigned int delay) +{ + static uint32_t end_addr = SSD1306_WIDTH * 8; + char lost_bit = 0; + + for(uint8_t times = 0; times < pixels; times++) { + for(uint32_t addr = 0; addr < end_addr; addr++) { + + // In the first bank we dont need to keep the lost bit + if (addr > 0x79) { + lost_bit = SSD1306_Buffer[addr] & 0x01; + } + + // Shift one pixel "up" + SSD1306_Buffer[addr] >>= 1; + + // In the first bank we dont need to do this + if (addr > 0x79) { + // Move the saved bit from the LSB to the MSB + lost_bit <<= 7; + // Add the saved bit to the bank above it + SSD1306_Buffer[addr - SSD1306_WIDTH] |= lost_bit; + } + } + ssd1306_UpdateScreen(); + HAL_Delay(delay); } }