Skocz do zawartości

E-paper 2.9 (aka Waveshare black-red-white) poszukiwana biblioteka


DeadGeneratio

Pomocna odpowiedź

Jak w temacie, zaufałem marce WeAct pod względem mikrokontrolerów, ale niestety ciężko z znalezieniem biblioteki do 2,9 calowego modułu wyświetlacza w technologii e-paper, w wersji black, white and red. Chciałem wzorować się na module od waveshare, mają biblioteki do stm32 f103, ale tylko dla wersji black-white. Z kolei na githubie od WeAct, link obok: https://github.com/WeActStudio/WeActStudio.EpaperModule/tree/master nie ma wersji dla STM. Starałem się przejrzeć datasheet jak zrobiłem to dla czujnika ciśnienia i temperatury STH czy tam SHT31 i zrobiłem komplet funkcji które działały na jego podstawie, ale ten datashhet mnie niestety przerasta. Sądziłem, że będzie to najzwyklejszy ekran a to ma więcej funkcji niż stare telefony, a tak przynajmniej datasheet wygląda. Ma ktoś może taką bibliotekę, wie gdzie szukać bądź zetknął się już z tym modułem?

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

(edytowany)

W screen.c mam:

#include "screen.h"
#include "fonts.h"

#include "stm32h7xx_hal.h"

a wcześniej gdy ustawiłem rozdrobnienie programu osobne pliki .c oraz .h

#include "screen.h"
#include "fonts.h"

#include "stm32h7xx_hal.h"
#include "spi.h"
#include "gpio.h"
  

Wiem, że to głupie z tym spi.h skoro ja tworzę tutaj instancję SPI, ale postanowiłem stworzyć początkowo w CUBE IDE instancję SPI, a potem w kodzie nie dodawać części odpowiedzialnej za inicjowanie SPI. To co teraz widać jest próbą stworzenia tej instancji bez pomocy CUBE IDE.

Plik screen.h wygląda następująco:

#ifndef INC_SCREEN_H_
#define INC_SCREEN_H_

#include "stm32h7xx_hal.h"

I oczywiście, w pliku main.c mam dołączenie screen.h

Edytowano przez DeadGeneratio
Link do komentarza
Share on other sites

Udało mi się zmodyfikować kod - SPI2 jest inicjalizowane przez CUBE IDE z zawartością analogiczną do tej co w kodzie:

void MX_SPI2_Init(void)
{

  /* USER CODE BEGIN SPI2_Init 0 */

  /* USER CODE END SPI2_Init 0 */

  /* USER CODE BEGIN SPI2_Init 1 */

  /* USER CODE END SPI2_Init 1 */
  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_1LINE;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 0x0;
  hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  hspi2.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
  hspi2.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
  hspi2.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi2.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi2.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
  hspi2.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
  hspi2.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
  hspi2.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
  hspi2.Init.IOSwap = SPI_IO_SWAP_DISABLE;
  if (HAL_SPI_Init(&hspi2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI2_Init 2 */

  /* USER CODE END SPI2_Init 2 */

}

oraz wejścia/wyjścia GPIO także:

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, SPI2_RES_Pin|SPI2_DC_Pin|SPI2_CS_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : PBPin PBPin PBPin */
  GPIO_InitStruct.Pin = SPI2_RES_Pin|SPI2_DC_Pin|SPI2_CS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = SPI2_BUSY_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(SPI2_BUSY_GPIO_Port, &GPIO_InitStruct);

}

Przyszedł czas na testowanie wyświetlacza i mam mały zonk, bo niestety robię to na chłopski rozum z racji braku poradników bądź toturiali, a i z ekranem typu e-papier mam doczynienia pierwszy raz. Przeglądając plik screen.h:

#ifndef INC_SCREEN_H_
#define INC_SCREEN_H_

#include "stm32h7xx_hal.h"

#define EPD_W 128
#define EPD_H 296

#define EPD_OK 0
#define EPD_ERROR 1

#define EPD_ROTATE_0 0
#define EPD_ROTATE_90 90
#define EPD_ROTATE_180 180
#define EPD_ROTATE_270 270

#define EPD_COLOR_WHITE 0xFF
#define EPD_COLOR_BLACK 0x00
#define EPD_COLOR_RED EPD_COLOR_BLACK

#define EPD_FONT_SIZE8x6 (8)
#define EPD_FONT_SIZE12x6 (12)
#define EPD_FONT_SIZE16x8 (16)
#define EPD_FONT_SIZE24x12 (24)

#define EPD_DEEPSLEEP_MODE1 (0x01)
#define EPD_DEEPSLEEP_MODE2 (0x03)

#define EPD_W_BUFF_SIZE ((EPD_W % 8 == 0) ? (EPD_W / 8) : (EPD_W / 8 + 1))
    typedef struct
    {
        uint8_t *Image;
        uint16_t Width;
        uint16_t Height;
        uint16_t WidthMemory;
        uint16_t HeightMemory;
        uint16_t Color;
        uint16_t Rotate;
        uint16_t WidthByte;
        uint16_t HeightByte;
    } EPD_PAINT;
    extern EPD_PAINT EPD_Paint;

    uint8_t epd_init(void);
    uint8_t epd_init_partial(void);
    void epd_enter_deepsleepmode(uint8_t mode);
    void epd_init_internalTempSensor(void);
    void epd_update(void);
    void epd_update_partial(void);
    void epd_display(uint8_t *Image1, uint8_t *Image2);
    void epd_displayBW(uint8_t *Image);
    void epd_displayBW_partial(uint8_t *Image);
    void epd_displayRED(uint8_t *Image);

    void epd_paint_newimage(uint8_t *image, uint16_t Width, uint16_t Height, uint16_t Rotate, uint16_t Color);
    void epd_paint_setpixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color);
    void epd_paint_selectimage(uint8_t *image);
    void epd_paint_clear(uint16_t color);
    void epd_paint_drawPoint(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color);
    void epd_paint_drawLine(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color);
    void epd_paint_drawRectangle(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color, uint8_t mode);
    void epd_paint_drawCircle(uint16_t X_Center, uint16_t Y_Center, uint16_t Radius, uint16_t Color, uint8_t mode);
    void epd_paint_showChar(uint16_t x, uint16_t y, uint16_t chr, uint16_t size1, uint16_t color);
    void epd_paint_showString(uint16_t x, uint16_t y, uint8_t *chr, uint16_t size1, uint16_t color);
    void epd_paint_showNum(uint16_t x, uint16_t y, uint32_t num, uint16_t len, uint16_t size1, uint16_t color);
    void epd_paint_showChinese(uint16_t x, uint16_t y, uint16_t num, uint16_t size1, uint16_t color);
    void epd_paint_showPicture(uint16_t x, uint16_t y, uint16_t sizex, uint16_t sizey, const uint8_t BMP[], uint16_t Color);

#ifdef __cplusplus
}
#endif


#endif

widzę, że wypadałoby zainicjalizować ekran - epd_init(). Potem dla testu wykonuję epd_paint_clear(0xFF), czyli cały ekran czyszczę na dany kolor, a przynajmniej tak myślałem. Nic się nie działo więc dorzuciłem epd_update() oraz na koniec epd_enter_deepsleepmode(), ale ekran dostaje padaczki. Stwierdziłem, że okej, być może funkcja czyści ekran z tego tylko koloru co zadeklaruję, więc trzykrotnie wywołałem czyszczenie poszczególnego koloru, ale ekran dalej działa tak samo upośledzenie. Ktoś domyśla się co może być przyczyną? W załączniku nowy kod.

Nagranie działania ekranu: https://drive.google.com/file/d/1GSGuvmLHbmtp-CNvZ1q1f0HsIFLJ5cqm/view?usp=sharing

Namieszane_w_SPIv2.zip

Link do komentarza
Share on other sites

(edytowany)

Niestety z takim rozbudowanym albo tak napisanym dokumentem nie jestem w stanie sobie poradzić samodzielnie. Staram się analizować kod analogiczny dla APM i sprawdzać sobie funkcje poszczególne a nawet odtworzyć kod, ale idzie bardzo kiepsko.

Na pewno muszę zainicjować wyświetlacz. Z inżynierii wstecznej wychodzi, że należy wykorzystać rejestr 0x01, a następnie wysłać wartość 0x27, 0x01 oraz 0x01. W sumie czy należy nie wiem, ktoś tak zrobił i w ten sposób wyświetlacz zadziałał.

image.thumb.png.50a05ac0968e47bb372e9111b7674dda.png

Z kodu potem wynika, że na mikrokontrolerze przygotowana jest mapa bitowa, która potem jest wysyłana komendą epd_display, czyli rejestr 0x24 dla koloru czarno-białego i rejestr 0x26 dla czerwonego. Wysyłane są wtedy dane do RAMu. Ale najgorsze jest to, że skoro rozdzielczość wynosi z grubsza  100x300 to powinienem mieć około 30000 znaków w tablicy. A przykładowe obrazy w pliku bmp mają maksymalnie 4000 znaków.

Na samym końcu wywołać wysłanie zawartości RAMu z wyświetlacza na sam wyświetlacz do czego służy rejestr 0x21, a następnie wysłanie komendy przy DC = 1, 0b00000000 - screen poniżej z dokumentacji.

image.thumb.png.f6965266fdc101ca3b977c048ebefd6c.png

Po aktualizacji na pewno wejście w deepsleep mode, czyli 0x10, a potem DC = 1 oraz 0b00000001.

image.thumb.png.312410705c5803a8def085c1871de1a9.png

 

 

Edytowano przez DeadGeneratio
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.