11.セグメントLEDプロジェクト
11.1.7セグメントLED(Sparkfun)表示ー時刻、温度表示
プロジェクト名:Led7segment
プロジェクト概要
LCDは表示が見にくい他、デザイン的に物足りない場合があります。このような場合、7セグメントLEDが使用できます。本プロジェクトはSparkfunのセグメント4桁LED(青)を使用したプロジェクトです。接続はシリアル、SPI、I2Cから選択できます。当初I2Cで接続していましたが、動作が不安定でシリアル接続に切り替えました。色は赤、白、青から選択できます。Picoではシリアル出力が3Vロジックで、LEDへの電源も3Vになっています。この場合、5V電源を与えた場合に比べてLEDの輝度が多少落ちます。このため、シリアル接続にレベル変換モジュールBSS138を使用しています。シリアル接続のボーレイトは初期状態で9600です。UART1の初期化処理は以下となります。
#define UART_ID uart1
#define BAUD_RATE 9600
#define UART_TX_PIN 4
uart_init(UART_ID, BAUD_RATE);
uart_set_translate_crlf(UART_ID, false);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
本プロジェクトでは、UARTライブラリの他にオンボード温度の読み込みに必要なADC、時刻処理に必要なRTCライブラリを使用します。以下のincludeが必要です。
#include "hardware/adc.h"
#include "hardware/rtc.h"
#include "hardware/uart.h"
同時にCMakelists.txtにも以下、追加します。
target_link_libraries(Led7segment hardware_adc hardware_rtc hardware_uart)
LEDの場合、消費電流が問題になると思います。
Parameter Min Typ. Max
Supply voltage 2.4V 3.3-5V 5.5V
Supply current (Vcc=3.3V) 3.8mA 7.9mA
Supply current (Vcc=5V) 6.9mA 14.1mA
上記仕様ではPicoの最大出力電流が50mAですので、範囲内です。
部品リスト
Sparkfunシリアル接続7セグメント4桁LED(青) 1 スイッチサイエンス
タクトスイッチ 1
配線図

ソースリスト
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/adc.h"
#include "hardware/rtc.h"
#include "hardware/uart.h"
//#define PICO_DEFAULT_LED_PIN 25
#define LED_PIN PICO_DEFAULT_LED_PIN
#define BUTTON_PIN 10
#define UART_ID uart1
#define BAUD_RATE 9600
#define UART_TX_PIN 4
//10.2章参照 -------
int WaitTerminalStartup()
//---------------------
void InitAdc() {
adc_init();
adc_set_temp_sensor_enabled(true);
adc_select_input(4);
}
float ReadAdcTemperature() {
float conversionFactor = 3.3f / (1 << 12);
float tempV = (float)adc_read() * conversionFactor;
float tempC = 27.0f - (tempV - 0.706f) / 0.001721f;
return tempC;
}
void InitRtc() {
char datetime_buf[256];
char *datetime_str = &datetime_buf[0];
//Start on 2023/5/9 Tuesday 10:24:00
datetime_t t = {
.year = 2023,
.month = 5,
.day = 9,
.dotw = 2, // 0:Sunday - 5:Friday
.hour = 10,
.min = 24,
.sec = 00
};
rtc_init();
rtc_set_datetime(&t);
sleep_ms(1);
}
//Sseg control --------
void sseg_reset()
{
uint8_t buf[8];
buf[0] = 0x81;
uart_write_blocking(UART_ID, buf, 1);
sleep_ms(10);
}
bool sseg_set_i2c_addr(int addr)
{
if((addr < 1) || (126 < addr)){
return false;
}
uint8_t buf[8];
buf[0] = 0x80;
buf[1] = addr;
uart_write_blocking(UART_ID, buf, 2);
sleep_ms(10);
return true;
}
bool sseg_set_baudrate(int baudrate)
{
if((baudrate < 0) || (11 < baudrate)){
return false;
}
uint8_t buf[8];
buf[0] = 0x7F;
buf[1] = baudrate;
uart_write_blocking(UART_ID, buf, 2);
sleep_ms(10);
return true;
}
bool sseg_segment_control(int digit, int segment)
{
if((digit < 0) || (3 < digit)){
return false;
}
if((segment < 0) || (127 < segment)){
return false;
}
uint8_t buf[8];
uint8_t dbuf[4] = {0x7B,0x7C,0x7D,0x7E};
buf[0] = dbuf[digit];
buf[1] = segment;
uart_write_blocking(UART_ID, buf, 2);
sleep_ms(10);
return true;
}
bool sseg_set_brightness(int value)
{
if((value < 0) || (100 < value)){
return false;
}
uint8_t buf[8];
buf[0] = 0x7A;
buf[1] = value;
uart_write_blocking(UART_ID, buf, 2);
sleep_ms(10);
return true;
}
bool sseg_set_cursor(int value)
{
if((value < 0) || (3 < value)){
return false;
}
uint8_t buf[8];
buf[0] = 0x79;
buf[1] = value;
uart_write_blocking(UART_ID, buf, 2);
sleep_ms(10);
return true;
}
void sseg_set_decimal(bool dec0,bool dec1,bool dec2,bool dec3, bool colon, bool apostrophe)
{
uint8_t buf[8];
buf[0] = 0x77;
buf[1] = (uint8_t)apostrophe << 5;
buf[1] |= (uint8_t)colon << 4;
buf[1] |= (uint8_t)dec3 << 3;
buf[1] |= (uint8_t)dec2 << 2;
buf[1] |= (uint8_t)dec1 << 1;
buf[1] |= (uint8_t)dec0;
uart_write_blocking(UART_ID, buf, 2);
sleep_ms(10);
}
void sseg_clear_display()
{
uint8_t buf[8];
buf[0] = 0x76;
uart_write_blocking(UART_ID, buf, 1);
sleep_ms(10);
}
void sseg_display_data(char *data, int len)
{
uart_write_blocking(UART_ID, data, len);
sleep_ms(10);
}
int main()
{
stdio_init_all();
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
gpio_init(BUTTON_PIN);
gpio_set_dir(BUTTON_PIN, GPIO_IN);
gpio_pull_down(BUTTON_PIN);
gpio_put(PICO_DEFAULT_LED_PIN, 0);
gpio_put(LED_PIN, 0);
uart_init(UART_ID, BAUD_RATE);
uart_set_translate_crlf(UART_ID, false);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
WaitTerminalStartup();
printf("\nTerminal connected\n");
InitAdc();
InitRtc();
sseg_clear_display();
sseg_set_brightness(100);
datetime_t nowdt;
int presec = -1;
char buf[128];
int i = 0;
bool colonOn = false;
int valueMode = 1; //0:time 1:temperature
while(true) {
uint8_t ret = gpio_get(BUTTON_PIN);
if(ret == 1) {
if(valueMode == 0){
valueMode = 1;
} else {
valueMode = 0;
}
}
rtc_get_datetime(&nowdt);
if(presec != nowdt.sec)
{
float temp = ReadAdcTemperature();
sprintf(buf, "%5.2f", temp);
printf("%4d/%02d/%02d %02d:%02d:%02d %4.1f C\n",
nowdt.year, nowdt.month, nowdt.day,nowdt.hour,nowdt.min, nowdt.sec, temp);
if(valueMode == 0) {
sseg_set_cursor(0);
sprintf(buf, "%02d%02d", nowdt.hour,nowdt.min);
sseg_display_data(buf, 4);
if(colonOn){
colonOn = false;
} else {
colonOn = true;
}
sseg_set_decimal(false,false,false,false, colonOn, false);
} else {
sseg_set_cursor(0);
sprintf(buf, " %3.0f", temp*10.0f);
sseg_display_data(buf, 4);
sseg_set_decimal(false,false,true,false, false, false);
}
}
presec = nowdt.sec;
sleep_ms(200);
}
return 0;-
}
タクトスイッチを押す毎に、時刻表示とオンボード温度表示が切り替わります。
コメントをお書きください