From a14a1fa5caa8a7a7f8ec447c66e332b3d7800445 Mon Sep 17 00:00:00 2001 From: Wataru KUNINO Date: Tue, 17 Dec 2024 21:09:36 +0900 Subject: [PATCH] =?UTF-8?q?lib=5Fled.ino=E3=81=AEESP=20IDF=205.0=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- atom/ex00_hello/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex01_led/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex02_sw/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex02_sw_line/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex03_lum/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex04_lcd/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex05_hum/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex06_pir/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex06_pir_line/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex07_gps/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex08_ir_out/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom/ex09_talk/lib_led.ino | 266 +++++++++++++++++++++++++++++++- atom_s3/ex01_led/lib_led.ino | 270 ++++++++++++++++++++++++++++++++- 13 files changed, 3433 insertions(+), 29 deletions(-) diff --git a/atom/ex00_hello/lib_led.ino b/atom/ex00_hello/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex00_hello/lib_led.ino +++ b/atom/ex00_hello/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex01_led/lib_led.ino b/atom/ex01_led/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex01_led/lib_led.ino +++ b/atom/ex01_led/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex02_sw/lib_led.ino b/atom/ex02_sw/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex02_sw/lib_led.ino +++ b/atom/ex02_sw/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex02_sw_line/lib_led.ino b/atom/ex02_sw_line/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex02_sw_line/lib_led.ino +++ b/atom/ex02_sw_line/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex03_lum/lib_led.ino b/atom/ex03_lum/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex03_lum/lib_led.ino +++ b/atom/ex03_lum/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex04_lcd/lib_led.ino b/atom/ex04_lcd/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex04_lcd/lib_led.ino +++ b/atom/ex04_lcd/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex05_hum/lib_led.ino b/atom/ex05_hum/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex05_hum/lib_led.ino +++ b/atom/ex05_hum/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex06_pir/lib_led.ino b/atom/ex06_pir/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex06_pir/lib_led.ino +++ b/atom/ex06_pir/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex06_pir_line/lib_led.ino b/atom/ex06_pir_line/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex06_pir_line/lib_led.ino +++ b/atom/ex06_pir_line/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex07_gps/lib_led.ino b/atom/ex07_gps/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex07_gps/lib_led.ino +++ b/atom/ex07_gps/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex08_ir_out/lib_led.ino b/atom/ex08_ir_out/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex08_ir_out/lib_led.ino +++ b/atom/ex08_ir_out/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom/ex09_talk/lib_led.ino b/atom/ex09_talk/lib_led.ino index fb52048..ef18540 100644 --- a/atom/ex09_talk/lib_led.ino +++ b/atom/ex09_talk/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -73,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -98,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -106,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -172,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// } diff --git a/atom_s3/ex01_led/lib_led.ino b/atom_s3/ex01_led/lib_led.ino index 0a1dc3e..ef18540 100644 --- a/atom_s3/ex01_led/lib_led.ino +++ b/atom_s3/ex01_led/lib_led.ino @@ -1,12 +1,148 @@ /*********************************************************************** LED制御ドライバ RGB LED WS2812 - Copyright (c) 2022 Wataru KUNINO + Copyright (c) 2022-2024 Wataru KUNINO ************************************************************************ MITライセンスで配布します。権利表示の改変は禁止します。全て無保証です。 本ソースコードには末尾に示すライセンス(The Unlicense)に基づいたコードを 含みます。 ***********************************************************************/ +#ifndef ESP_IDF_VERSION + #define ESP_IDF_VERSION 0 +#endif +#ifndef ESP_IDF_VERSION_VAL + #define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + // https://github.com/espressif/esp-idf/blob/master/components/esp_common/include/esp_idf_version.h +#endif + +void print_esp_idf_version(){ + Serial.print(ESP_IDF_VERSION >> 16); + Serial.print("."); + Serial.print((ESP_IDF_VERSION >> 8) % 255); + Serial.print("."); + Serial.println(ESP_IDF_VERSION % 255); +} + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0) + +rmt_data_t led_data[24]; +int _PIN_LED = 0; + +void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; + uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); + for (int bit = 0; bit < 24; bit++) { + if ((rgb & (1 << (23 - bit))) ) { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 8; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 4; + } else { + led_data[bit].level0 = 1; + led_data[bit].duration0 = 4; + led_data[bit].level1 = 0; + led_data[bit].duration1 = 8; + } + } + rmtWrite(_PIN_LED, led_data, 24, RMT_WAIT_FOR_EVER); +} + +void led(int brightness){ // グレースケール制御 + if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 + led(brightness,brightness,brightness); // RGB全て同値でLED制御 +} + +void led_on(){ // LED制御の停止 + led(30); // LEDの消灯 +} + +void led_off(){ // LED制御の停止 + led(0); // LEDの消灯 +} + +void led_setup(int pin){ + _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, Espressif Systems Remote Control Transceiver, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, (PIN="+String(pin)+") real tick set to: 100ns"); + rmtInit(_PIN_LED, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000); +} + +/*********************************************************************** +参考文献 RMT Write RGB LED +Remote Control Transceiver (RMT) peripheral was designed to act as an +infrared transceiver. +https://docs.espressif.com/projects/arduino-esp32/en/latest/api/rmt.html +************************************************************************ + +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + ** + * @brief This example demonstrates usage of RGB LED driven by RMT + * + * The output is a visual WS2812 RGB LED color moving in a 8 x 4 LED matrix + * Parameters can be changed by the user. In a single LED circuit, it will just blink. + * + +void setup() { + Serial.begin(115200); + if (!rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { + Serial.println("init sender failed\n"); + } + Serial.println("real tick set to: 100ns"); +} + +int color[] = {0x55, 0x11, 0x77}; // Green Red Blue values +int led_index = 0; + +void loop() { + // Init data with only one led ON + int led, col, bit; + int i = 0; + for (led = 0; led < NR_OF_LEDS; led++) { + for (col = 0; col < 3; col++) { + for (bit = 0; bit < 8; bit++) { + if ((color[col] & (1 << (7 - bit))) && (led == led_index)) { + led_data[i].level0 = 1; + led_data[i].duration0 = 8; + led_data[i].level1 = 0; + led_data[i].duration1 = 4; + } else { + led_data[i].level0 = 1; + led_data[i].duration0 = 4; + led_data[i].level1 = 0; + led_data[i].duration1 = 8; + } + i++; + } + } + } + // make the led travel in the panel + if ((++led_index) >= NR_OF_LEDS) { + led_index = 0; + } + // Send the data and wait until it is done + rmtWrite(BUILTIN_RGBLED_PIN, led_data, NR_OF_ALL_BITS, RMT_WAIT_FOR_EVER); + delay(100); +} +***********************************************************************/ + +#else // ESP_IDF_VERSION < 5.0.0 + #include "driver/rmt.h" // Configure these based on your project needs using menuconfig ******** @@ -38,9 +174,7 @@ void ws2812_control_init(void){ config.gpio_num = (gpio_num_t)_PIN_LED; config.mem_block_num = 3; // glancek commented on 30 Mar 2021; not work without flag = 0 - #ifndef M5STACK_V1 - config.flags = 0; - #endif + config.flags = 0; config.tx_config.loop_en = false; config.tx_config.carrier_en = false; config.tx_config.idle_output_en = true; @@ -75,8 +209,9 @@ void setup_rmt_data_buffer(struct led_state new_state){ } } -/* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 // void led(int r,int g,int b){ // LEDにカラーを設定 + if(_PIN_LED == 0) return; uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); struct led_state new_state; new_state.leds[0] = rgb; @@ -100,6 +235,11 @@ void led_off(){ // LED制御の停止 void led_setup(int pin){ _PIN_LED = pin; + if(_PIN_LED == 0) return; + Serial.println("RMT Init, JSchaenzle/ESP32-NeoPixel-WS2812-RMT, forked by Wataru KUNINO"); + Serial.print("RMT Init, ESP_IDF_VERSION: "); + print_esp_idf_version(); + Serial.println("RMT Init, PIN="+String(pin)); ws2812_control_init(); led_off(); } @@ -108,6 +248,9 @@ void led_setup(){ led_setup(_PIN_LED); } +#endif + + /****************************************************************************** lib_led.ino ******************************************************************************* @@ -174,3 +317,120 @@ SOFTWARE. For more information, please refer to ***********************************************************************/ + +// /*********************************************************************** +// LED制御ドライバ RGB LED WS2812 +// 解説= https://bokunimo.net/blog/esp/1522/ +// Copyright (c) 2021 Wataru KUNINO +// ***********************************************************************/ +// #define T0H_ns 320 // b0信号Hレベル時間(ns) +// #define T0L_ns 1200 -320 // b0信号Lレベル時間(ns) +// #define T1H_ns 640 // b1信号Hレベル時間(ns) +// #define T1L_ns 1200 -640 // b1信号Lレベル時間(ns) +// +// int _PIN_LED = 8; +// int T_Delay,T0H_num,T0L_num,T1H_num,T1L_num; // 待ち時間カウンタ値 +// +// /* 引数nsに代入された待ち時間(ns)に対応する待ち時間処理回数を求める */ +// int _led_delay(int ns){ // カウンタ設定処理部 +// volatile uint32_t i; // 繰り返し処理用変数i +// uint32_t target, counts=0; // 目標時刻,試行繰返し数 +// ns -= T_Delay; // 処理遅延分を減算 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// do{ // 繰り返し処理の開始 +// i = ++counts; // 試行回数を増やしてiに +// target = micros() + ns / 10; // 目標時刻を設定 +// while(i>0) i--; // 待ち時間処理の実行 +// }while(micros() < target); // 目標未達成時に繰返し +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return (counts + 50)/100; // 繰り返し回数を応答 +// } +// +// /* 信号操作に必要な処理時間を算出する。戻り値は必要時間(ns) */ +// int _initial_delay(){ // 初期ディレイ測定部 +// volatile uint32_t i=0; // 繰り返し処理用変数i +// uint32_t start, t, counts; // 開始時刻,試行繰返し数 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start; // 経過時間をtに代入 +// start = micros(); // 開始時刻の保持 +// counts = 0; // カウンタのリセット +// do{ // 繰り返し処理の開始 +// counts++; // カウント +// digitalWrite(_PIN_LED,LOW); // (被測定対象)GPIO制御 +// while(i>0); // (被測定対象)while +// }while(counts < 1000); // 目標未達成時に繰返し +// t = micros() - start - t; // 対象処理に要した時間 +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// return t; // 繰り返し回数を応答 +// } +// +// /* 引数r,g,bに代入された色をLEDに送信する。値は0~255の範囲で設定 */ +// void led(int r,int g,int b){ // LEDにカラーを設定 +// digitalWrite(_PIN_LED,LOW); // Lレベル +// delayMicroseconds(300); // 280us以上を維持 +// volatile int TH, TL; // H/Lレベル時間保持用 +// uint32_t rgb = (g & 0xff) << 16 | (r & 0xff) << 8 | (b & 0xff); +// +// // vTaskSuspendAll(); // OSによるSwapOutの防止 +// // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3 +// // /api-reference/system/freertos.html#task-api +// yield(); // 割り込み動作 +// portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; // 排他制御用 +// portENTER_CRITICAL_ISR(&mutex); // 割り込みの禁止 +// for(int b=23;b >= 0; b--){ // 全24ビット分の処理 +// if(rgb & (1<0) TH--; // 待ち時間処理 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// }else{ // THが0の時 +// digitalWrite(_PIN_LED,HIGH); // Hレベルを出力 +// digitalWrite(_PIN_LED,LOW); // Lレベルを出力 +// while(TL>0) TL--; // 待ち時間処理 +// } +// } +// portEXIT_CRITICAL_ISR(&mutex); // 割り込み許可 +// // if(!xTaskResumeAll()) taskYIELD(); // OSの再開 +// } +// +// void led(int brightness){ // グレースケール制御 +// if(brightness > 0xff) brightness = 0xff; // 256以上時に255に設定 +// led(brightness,brightness,brightness); // RGB全て同値でLED制御 +// } +// +// void led_off(){ // LED制御の停止 +// led(0); // LEDの消灯 +// digitalWrite(_PIN_LED,LOW); // リセット(Lレベル) +// delayMicroseconds(300); // 280us以上を維持 +// } +// +// void led_setup(int pin){ +// _PIN_LED = pin; +// pinMode(_PIN_LED,OUTPUT); // ポートを出力に設定 +// digitalWrite(_PIN_LED,LOW); +// delay(100); +// T_Delay = _initial_delay(); // 信号処理遅延を算出 +// T0H_num=_led_delay(T0H_ns); // 待ち時間処理回数変換 +// T0L_num=_led_delay(T0L_ns); +// T1H_num=_led_delay(T1H_ns); +// T1L_num=_led_delay(T1L_ns); +// led_off(); +// } +// +// void led_setup(){ +// led_setup(_PIN_LED); +// }