Comments (20)
Files with the ico extension cannot be drawn.
You need to convert the image file to PNG or JPEG format using something like ImageMagick.
JPEG display and PNG display are included in the sample project I provide.
https://github.com/nopnop2002/esp-idf-ili9340/blob/master/main/main.c#L848
https://github.com/nopnop2002/esp-idf-ili9340/blob/master/main/main.c#L922
However, it is not possible to display the image at any arbitrary position.
Always display the image in the center of the screen.
Since ESP32S2 has small RAM, there is a possibility that JPEG cannot be displayed due to insufficient memory.
To display an image in any position, you need to convert the image to BMP format using something like ImageMagick, and then resize the converted image to a smaller size.
It is necessary to develop a new function to display the resized image file in any position.
Based on the BMP display sample that I provide, you can develop a new function that displays BMP images in any position.
https://github.com/nopnop2002/esp-idf-ili9340/blob/master/main/main.c#L695
Displaying images is difficult, so you need to have a thorough understanding of image files.
Additionally, you need to understand the relationship between the number of pixels in the image file and the number of pixels on the screen.
from esp-idf-ili9340.
See i have just run the function of BMP test, the function is calling again and again but there is no output on the display.
from esp-idf-ili9340.
I would like to know the version of IDF you are using.
You can check it with the command below.
$ idf.py --version
ESP-IDF v5.1.2-695-gd922d4178f-dirty
I would like to know all your logging print.
from esp-idf-ili9340.
Added png icon display example.
You can display the PNG icon wherever you like.
https://github.com/nopnop2002/esp-idf-ili9340/blob/master/main/main.c#L2233
from esp-idf-ili9340.
from esp-idf-ili9340.
No such version exists.
The current stable version is below.
https://github.com/espressif/esp-idf/releases
from esp-idf-ili9340.
now i have to do to solve my problem?
from esp-idf-ili9340.
Installation of the stable version of ESP-IDF.
https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/
from esp-idf-ili9340.
Thank you @nopnop2002 , now the icon is displaying on the LCD. I am also facing another issue that if i write something on the LCD and then write an other line on the same postion. It will not remove the previous data, and rewrite on the previous data. Can you tell me how can i update the LCD and write the new line on same postion.
from esp-idf-ili9340.
lcdFillScreen(dev, WHITE);
strcpy((char *)ascii, "ABCD");
lcdDrawString(dev, fx, 0, 0, ascii, BLACK);
sleep(10);
lcdDrawString(dev, fx, 0, 0, ascii, WHITE);
strcpy((char *)ascii, "abcd");
lcdDrawString(dev, fx, 0, 0, ascii, BLACK);
from esp-idf-ili9340.
Thank you @nopnop2002 . I really appreciate your effort and soory for asking to much queries. I am the new one in the embedded system field. So i am facing lot of issues.
from esp-idf-ili9340.
Now the issue i am facing is that i have to display the fingerprint icon and time at the same time. But when i run the code it just show the time and then wait and again refresh the screen.
from esp-idf-ili9340.
if i comment the code portion of time from the app main function then just fingerprint icon is displayed on the LCD
from esp-idf-ili9340.
I can't figure out what the problem is just by looking at some of the code.
You can share your project using your github account.
from esp-idf-ili9340.
I have uploaded the code on my github account.
from esp-idf-ili9340.
The date and time obtained with Get_current_date_time() is 24 characters.
Therefore, an buffer of at least 25 bytes is required.
strcpy adds NULL to the end of buffer.
I (58073) wifi station: The current date/time is: [Thu Mar 28 16:18:47 2024]
I (58073) wifi station: strlen(strftime_buf)=24
//uint8_t ascii[24];
uint8_t ascii[25];
Get_current_date_time(Current_Date_Time);
I have found that there is no problem with this library, so I will close it.
from esp-idf-ili9340.
Sir just tell me what changes you have made to get the output. I have increased the size of buffer but i am still facing the issue.
from esp-idf-ili9340.
You need to change this.
#define EXAMPLE_ESP_WIFI_SSID "xxxxxxxxxxxxxxx"
#define EXAMPLE_ESP_WIFI_PASS "xxxxxxxxxxxxxxx"
#include <stdio.h>
#include <inttypes.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include "esp_attr.h"
#include "esp_sleep.h"
#include "esp_sntp.h"
#include <string.h>
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "esp_vfs.h"
#include "esp_spiffs.h"
#include "ili9340.h"
#include "fontx.h"
#include "bmpfile.h"
#include "decode_jpeg.h"
#include "decode_png.h"
#include "pngle.h"
#include "driver/gpio.h"
#define INTERVAL 400
#define WAIT vTaskDelay(INTERVAL)
static const char *TAG = "MAIN";
// You have to set these CONFIG value using menuconfig.
#define CONFIG_WIDTH 240
#define CONFIG_HEIGHT 320
#define EXAMPLE_ESP_WIFI_SSID "xxxxxxxxxxxxxxx"
#define EXAMPLE_ESP_WIFI_PASS "xxxxxxxxxxxxxxx"
static EventGroupHandle_t s_wifi_event_group;
/* The event group allows multiple bits for each event, but we only care about two events:
* - we are connected to the AP with an IP
* - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static const char *TAG1 = "wifi station";
char Current_Date_Time[100];
void time_sync_notification_cb(struct timeval *tv)
{
ESP_LOGI(TAG1, "Notification of a time synchronization event");
}
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
// if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY)
//{
esp_wifi_connect();
// s_retry_num++;
ESP_LOGI(TAG1, "retry to connect to the AP");
//} else {
// xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
ESP_LOGI(TAG1,"connect to the AP fail");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG1, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
//s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
void wifi_init_sta(void)
{
s_wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
NULL,
&instance_got_ip));
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
WIFI_EVENT_STA_DISCONNECTED,
&event_handler,
NULL,
NULL));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.password = EXAMPLE_ESP_WIFI_PASS,
/* Setting a password implies station will connect to all security modes including WEP/WPA.
* However these modes are deprecated and not advisable to be used. Incase your Access point
* doesn't support WPA2, these mode can be enabled by commenting below line */
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg = {
.capable = true,
.required = false
},
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK(esp_wifi_start() );
ESP_LOGI(TAG1, "wifi_init_sta finished.");
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
* happened. */
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG1, "connected to ap SSID:%s password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
} else if (bits & WIFI_FAIL_BIT) {
ESP_LOGI(TAG1, "Failed to connect to SSID:%s, password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
} else {
ESP_LOGE(TAG1, "UNEXPECTED EVENT");
}
/* The event will not be processed after unregister */
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
vEventGroupDelete(s_wifi_event_group);
}
void Get_current_date_time(char *date_time){
char strftime_buf[64];
time_t now;
struct tm timeinfo;
time(&now);
localtime_r(&now, &timeinfo);
setenv("TZ", "UTC-05:00", 1);
tzset();
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
ESP_LOGI(TAG1, "The current date/time is: [%s]", strftime_buf);
ESP_LOGI(TAG1, "strlen(strftime_buf)=%d", strlen(strftime_buf));
strcpy(date_time,strftime_buf);
}
static void initialize_sntp(void)
{
ESP_LOGI(TAG1, "Initializing SNTP");
sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, "pool.ntp.org");
sntp_set_time_sync_notification_cb(time_sync_notification_cb);
#ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH
sntp_set_sync_mode(SNTP_SYNC_MODE_SMOOTH);
#endif
sntp_init();
}
static void obtain_time(void)
{
initialize_sntp();
// wait for time to be set
time_t now = 0;
struct tm timeinfo = { 0 };
int retry = 0;
const int retry_count = 10;
while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry < retry_count) {
ESP_LOGI(TAG1, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
time(&now);
localtime_r(&now, &timeinfo);
}
void Set_SystemTime_SNTP() {
time_t now;
struct tm timeinfo;
time(&now);
localtime_r(&now, &timeinfo);
// Is time set? If not, tm_year will be (1970 - 1900).
if (timeinfo.tm_year < (2016 - 1900)) {
ESP_LOGI(TAG1, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
obtain_time();
// update 'now' variable with current time
time(&now);
}
}
/********************************************************************************************************************************/
void ShowPngImage(TFT_t * dev, char * file, int width, int height, int xpos, int ypos) {
// open PNG file
FILE* fp = fopen(file, "rb");
if (fp == NULL) {
ESP_LOGW(__FUNCTION__, "File not found [%s]", file);
return;
}
char buf[1024];
size_t remain = 0;
int len;
int _width = width;
if (width > 240) _width = 240;
int _height = height;
if (height > 320) _height = 320;
pngle_t *pngle = pngle_new(_width, _height);
pngle_set_init_callback(pngle, png_init);
pngle_set_draw_callback(pngle, png_draw);
pngle_set_done_callback(pngle, png_finish);
double display_gamma = 2.2;
pngle_set_display_gamma(pngle, display_gamma);
while (!feof(fp)) {
if (remain >= sizeof(buf)) {
ESP_LOGE(__FUNCTION__, "Buffer exceeded");
while(1) vTaskDelay(1);
}
len = fread(buf + remain, 1, sizeof(buf) - remain, fp);
if (len <= 0) {
//printf("EOF\n");
break;
}
int fed = pngle_feed(pngle, buf, remain + len);
if (fed < 0) {
ESP_LOGE(__FUNCTION__, "ERROR; %s", pngle_error(pngle));
while(1) vTaskDelay(1);
}
remain = remain + len - fed;
if (remain > 0) memmove(buf, buf + fed, remain);
}
fclose(fp);
uint16_t pngWidth = pngle_get_width(pngle);
uint16_t pngHeight = pngle_get_height(pngle);
ESP_LOGD(__FUNCTION__, "pngWidth=%d pngHeight=%d", pngWidth, pngHeight);
int _xpos = xpos - (pngHeight/2);
int _ypos = ypos - (pngWidth/2);
ESP_LOGD(__FUNCTION__, "xpos=%d ypos=%d _xpos=%d _ypos=%d", xpos, ypos, _xpos, _ypos);
uint16_t *colors = (uint16_t*)malloc(sizeof(uint16_t) * pngWidth);
if (colors == NULL) {
ESP_LOGE(__FUNCTION__, "malloc fail");
pngle_destroy(pngle, _width, _height);
return;
}
for(int y = 0; y < pngHeight; y++){
for(int x = 0;x < pngWidth; x++){
//pixel_png pixel = pngle->pixels[y][x];
//colors[x] = rgb565(pixel.red, pixel.green, pixel.blue);
colors[x] = pngle->pixels[y][x];
}
lcdDrawMultiPixels(dev, _xpos, y+_ypos, pngWidth, colors);
vTaskDelay(1);
}
free(colors);
pngle_destroy(pngle, _width, _height);
return;
}
void ILI9341(void *pvParameters)
{
// set font file
FontxFile fx16G[2];
FontxFile fx24G[2];
FontxFile fx32G[2];
FontxFile fx32L[2];
InitFontx(fx16G,"/spiffs/ILGH16XB.FNT",""); // 8x16Dot Gothic
InitFontx(fx24G,"/spiffs/ILGH24XB.FNT",""); // 12x24Dot Gothic
InitFontx(fx32G,"/spiffs/ILGH32XB.FNT",""); // 16x32Dot Gothic
InitFontx(fx32L,"/spiffs/LATIN32B.FNT",""); // 16x32Dot Latinc
FontxFile fx16M[2];
FontxFile fx24M[2];
FontxFile fx32M[2];
InitFontx(fx16M,"/spiffs/ILMH16XB.FNT",""); // 8x16Dot Mincyo
InitFontx(fx24M,"/spiffs/ILMH24XB.FNT",""); // 12x24Dot Mincyo
InitFontx(fx32M,"/spiffs/ILMH32XB.FNT",""); // 16x32Dot Mincyo
TFT_t dev;
#if CONFIG_XPT2046_ENABLE_SAME_BUS
ESP_LOGI(TAG, "Enable Touch Contoller using the same SPI bus as TFT");
int XPT_MISO_GPIO = CONFIG_XPT_MISO_GPIO;
int XPT_CS_GPIO = CONFIG_XPT_CS_GPIO;
int XPT_IRQ_GPIO = CONFIG_XPT_IRQ_GPIO;
int XPT_SCLK_GPIO = -1;
int XPT_MOSI_GPIO = -1;
#elif CONFIG_XPT2046_ENABLE_DIFF_BUS
ESP_LOGI(TAG, "Enable Touch Contoller using the different SPI bus from TFT");
int XPT_MISO_GPIO = CONFIG_XPT_MISO_GPIO;
int XPT_CS_GPIO = CONFIG_XPT_CS_GPIO;
int XPT_IRQ_GPIO = CONFIG_XPT_IRQ_GPIO;
int XPT_SCLK_GPIO = CONFIG_XPT_SCLK_GPIO;
int XPT_MOSI_GPIO = CONFIG_XPT_MOSI_GPIO;
#else
ESP_LOGI(TAG, "Disable Touch Contoller");
int XPT_MISO_GPIO = -1;
int XPT_CS_GPIO = -1;
int XPT_IRQ_GPIO = -1;
int XPT_SCLK_GPIO = -1;
int XPT_MOSI_GPIO = -1;
#endif
spi_master_init(&dev, CONFIG_MOSI_GPIO, CONFIG_SCLK_GPIO, CONFIG_TFT_CS_GPIO, CONFIG_DC_GPIO,
CONFIG_RESET_GPIO, CONFIG_BL_GPIO, XPT_MISO_GPIO, XPT_CS_GPIO, XPT_IRQ_GPIO, XPT_SCLK_GPIO, XPT_MOSI_GPIO);
#if CONFIG_ILI9225
uint16_t model = 0x9225;
#endif
#if CONFIG_ILI9225G
uint16_t model = 0x9226;
#endif
#if CONFIG_ILI9340
uint16_t model = 0x9340;
#endif
#if CONFIG_ILI9341
uint16_t model = 0x9341;
#endif
#if CONFIG_ST7735
uint16_t model = 0x7735;
#endif
#if CONFIG_ST7796
uint16_t model = 0x7796;
#endif
lcdInit(&dev, model, CONFIG_WIDTH, CONFIG_HEIGHT, CONFIG_OFFSETX, CONFIG_OFFSETY);
lcdSetFontDirection(&dev, DIRECTION90);
lcdFillScreen(&dev, WHITE);
while(1) {
//uint8_t ascii[24];
uint8_t ascii[25];
Get_current_date_time(Current_Date_Time);
strcpy((char *)ascii, Current_Date_Time);
lcdSetFontFill(&dev,WHITE);
lcdDrawString(&dev, fx24G, 210,20, ascii, BLACK);
vTaskDelay(110);
char file[32];
strcpy(file, "/icons/fingerprint.png");
ShowPngImage(&dev, file, CONFIG_WIDTH, CONFIG_HEIGHT, CONFIG_WIDTH/2, CONFIG_HEIGHT/2);
} // end while
// never reach here
vTaskDelete(NULL);
}
static void listSPIFFS(char * path) {
DIR* dir = opendir(path);
assert(dir != NULL);
while (true) {
struct dirent*pe = readdir(dir);
if (!pe) break;
ESP_LOGI(__FUNCTION__,"d_name=%s d_ino=%d d_type=%x", pe->d_name,pe->d_ino, pe->d_type);
}
closedir(dir);
}
esp_err_t mountSPIFFS(char * path, char * label, int max_files) {
esp_vfs_spiffs_conf_t conf = {
.base_path = path,
.partition_label = label,
.max_files = max_files,
.format_if_mount_failed =true
};
// Use settings defined above toinitialize and mount SPIFFS filesystem.
// Note: esp_vfs_spiffs_register is anall-in-one convenience function.
esp_err_t ret = esp_vfs_spiffs_register(&conf);
if (ret != ESP_OK) {
if (ret ==ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount or format filesystem");
} else if (ret== ESP_ERR_NOT_FOUND) {
ESP_LOGE(TAG, "Failed to find SPIFFS partition");
} else {
ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)",esp_err_to_name(ret));
}
return ret;
}
#if 0
ESP_LOGI(TAG, "Performing SPIFFS_check().");
ret = esp_spiffs_check(conf.partition_label);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "SPIFFS_check() failed (%s)", esp_err_to_name(ret));
return ret;
} else {
ESP_LOGI(TAG, "SPIFFS_check() successful");
}
#endif
size_t total = 0, used = 0;
ret = esp_spiffs_info(conf.partition_label, &total, &used);
if (ret != ESP_OK) {
ESP_LOGE(TAG,"Failed to get SPIFFS partition information (%s)",esp_err_to_name(ret));
} else {
ESP_LOGI(TAG,"Mount %s to %s success", path, label);
ESP_LOGI(TAG,"Partition size: total: %d, used: %d", total, used);
}
return ret;
}
void app_main(void)
{
esp_err_t ret1 = nvs_flash_init();
if (ret1 == ESP_ERR_NVS_NO_FREE_PAGES || ret1 == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret1 = nvs_flash_init();
}
ESP_ERROR_CHECK(ret1);
ESP_LOGI(TAG1, "ESP_WIFI_MODE_STA");
wifi_init_sta();
Set_SystemTime_SNTP();
/**************************************************************************************************************/
// Initialize NVS
ESP_LOGI(TAG, "Initialize NVS");
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// NVS partition was truncated and needs to be erased
// Retry nvs_flash_init
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK( err );
ESP_LOGI(TAG, "Initializing SPIFFS");
esp_err_t ret;
ret = mountSPIFFS("/spiffs", "storage0", 10);
if (ret != ESP_OK) return;
listSPIFFS("/spiffs/");
// Image file borrowed from here
// https://www.flaticon.com/packs/social-media-343
ret = mountSPIFFS("/icons", "storage1", 10);
if (ret != ESP_OK) return;
listSPIFFS("/icons/");
ret = mountSPIFFS("/images", "storage2", 14);
if (ret != ESP_OK) return;
listSPIFFS("/images/");
xTaskCreate(ILI9341, "ILI9341", 1024*6, NULL, 2, NULL);
}
from esp-idf-ili9340.
I run that code but i am not getting the output
from esp-idf-ili9340.
Narrow down the bad code by commenting out parts of the code.
from esp-idf-ili9340.
Related Issues (20)
- IMAGE
- IMAGE
- IMAGE HOT 4
- License HOT 2
- IMAGE HOT 3
- Guide how to use as esp-idf component HOT 7
- IMAGE HOT 1
- IMAGE HOT 35
- Use this library with platformio HOT 4
- Cant display ascii>127 HOT 6
- Often crashing on lcdDrawFillRect HOT 13
- xpt2046 issue HOT 44
- About coordinate systems
- A question. HOT 3
- Slow loading speed HOT 8
- display is mirrored HOT 1
- Turn DMA off HOT 3
- How to display jpeg or rgb565 from memory buffer ? HOT 4
- How to add new images/icons? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from esp-idf-ili9340.