10.LCDプロジェクト
10.1.16x2LCD表示ーI2Cデバイススキャン
プロジェクト名:ScanI2C
プロジェクトの概要
GROVEの16 x 2 LCDを使用したLCD表示プロジェクトです。Picoに接続されたデバイスを検出し、LCDに表示します。LCD自体のI2Cアドレス は0x27固定で、初期状態ではこのアドレスのみが表示されます。スイッチ1つが接続されており、このスイッチで上位アドレス00-07を切り替えます。スッチを押すごとに、LCDの上位アドレスが切り替わり、現在の上位アドレスはLCD1行目の0-7のカーソルで確認できます。
部品リスト
GROVEの16 x 2 LCD 1 スイッチサイエンス
タクトスイッチ 1
回路図
ソースリスト
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
//#define PICO_DEFAULT_LED_PIN 25
#define LED_PIN PICO_DEFAULT_LED_PIN
#define BUTTON_PIN 3
#define I2C_PORT i2c0
#define I2C_SDA 8
#define I2C_SCL 9
int ScanBuffer[128];
void ScanI2CBus() {
uint8_t rxdata;
for (int addr = 0; addr < 128; addr++) {
ScanBuffer[addr] = i2c_read_blocking(I2C_PORT, addr, &rxdata, 1, false);
sleep_ms(10);
}
}
//lcd
#define LCD_ADDR 0x27
// commands
const int LCD_CLEARDISPLAY = 0x01;
const int LCD_RETURNHOME = 0x02;
const int LCD_ENTRYMODESET = 0x04;
const int LCD_DISPLAYCONTROL = 0x08;
const int LCD_CURSORSHIFT = 0x10;
const int LCD_FUNCTIONSET = 0x20;
const int LCD_SETCGRAMADDR = 0x40;
const int LCD_SETDDRAMADDR = 0x80;
//display entry mode
const int LCD_ENTRYSHIFTINCREMENT = 0x01;
const int LCD_ENTRYLEFT = 0x02;
//display and cursor control
const int LCD_BLINKON = 0x01;
const int LCD_CURSORON = 0x02;
const int LCD_DISPLAYON = 0x04;
//display and cursor shift
const int LCD_MOVERIGHT = 0x04;
const int LCD_DISPLAYMOVE = 0x08;
//function set
const int LCD_5x10DOTS = 0x04;
const int LCD_2LINE = 0x08;
const int LCD_8BITMODE = 0x10;
//backlight control
const int LCD_BACKLIGHT = 0x08;
const int LCD_ENABLE_BIT = 0x04;
#define LCD_CHARACTER 1
#define LCD_COMMAND 0
#define MAX_LINES 2
#define MAX_CHARS 16
//#define MAX_LINES 4
//#define MAX_CHARS 20
#define DELAY_US 600
//lcd
void i2c_write_byte(uint8_t val) {
i2c_write_blocking(I2C_PORT, LCD_ADDR, &val, 1, false);
}
void lcd_toggle_enable(uint8_t val) {
sleep_us(DELAY_US);
i2c_write_byte(val | LCD_ENABLE_BIT);
sleep_us(DELAY_US);
i2c_write_byte(val & ~LCD_ENABLE_BIT);
sleep_us(DELAY_US);
}
void lcd_send_byte(uint8_t val, int mode) {
uint8_t high = mode | (val & 0xF0) | LCD_BACKLIGHT;
uint8_t low = mode | ((val << 4) & 0xF0) | LCD_BACKLIGHT;
i2c_write_byte(high);
lcd_toggle_enable(high);
i2c_write_byte(low);
lcd_toggle_enable(low);
}
void lcd_clear(void) {
lcd_send_byte(LCD_CLEARDISPLAY, LCD_COMMAND);
}
void lcd_set_cursor(int line, int position) {
int val;
switch (line) {
case 0:
val = 0x80 + position;
break;
case 1:
val = 0xc0 + position;
break;
case 2:
val = 0x94 + position;
break;
case 3:
val = 0xd4 + position;
break;
default:
break;
}
lcd_send_byte(val, LCD_COMMAND);
}
static void inline lcd_char(char val) {
lcd_send_byte(val, LCD_CHARACTER);
}
void lcd_string(const char *s) {
while(true) {
if(*s == 0) {
break;
}
lcd_char(*s);
s++;
}
}
void lcd_init() {
lcd_send_byte(0x03, LCD_COMMAND);
lcd_send_byte(0x03, LCD_COMMAND);
lcd_send_byte(0x03, LCD_COMMAND);
lcd_send_byte(0x02, LCD_COMMAND);
lcd_send_byte(LCD_ENTRYMODESET | LCD_ENTRYLEFT, LCD_COMMAND);
lcd_send_byte(LCD_FUNCTIONSET | LCD_2LINE, LCD_COMMAND);
lcd_send_byte(LCD_DISPLAYCONTROL | LCD_DISPLAYON, LCD_COMMAND);
lcd_clear();
}
int main()
{
char buf[128];
stdio_init_all();
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
gpio_put(LED_PIN, 0);
gpio_init(BUTTON_PIN);
gpio_set_dir(BUTTON_PIN, GPIO_IN);
gpio_pull_down(BUTTON_PIN);
i2c_init(I2C_PORT, 400*1000);
gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
gpio_pull_up(I2C_SDA);
gpio_pull_up(I2C_SCL);
ScanI2CBus();
lcd_init();
lcd_clear();
int yaddr = 0;
lcd_set_cursor(0, 0);
lcd_string("0123456789ABCDEF");
lcd_send_byte(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSORON, LCD_COMMAND);
uint8_t btnStatus = 0;
while(true) {
for(int i = 0; i < 16; i++) {
lcd_set_cursor(1, i);
if(ScanBuffer[yaddr*16 + i] >= 0) {
lcd_string("*");
} else {
lcd_string("-");
}
}
lcd_set_cursor(0, yaddr);
while(true) {
uint8_t ret = gpio_get(BUTTON_PIN);
if(ret != btnStatus) {
if((ret == 1) && (btnStatus == 0)) {
yaddr++;
if(yaddr >= 8){
yaddr = 0;
}
btnStatus = ret;
break;
}
}
btnStatus = ret;
sleep_ms(10);
}
}
return 0;
}
10.2.16x2LCD表示ー3分タイマー
プロジェクト名:Lcd16x2
プロジェクトの概要
GROVEの16 x 2 LCDを使用したLCD表示プロジェクトです。I2CでPicoと通信します。I2Cアドレス は0x27固定です。3分のカウントダウンタイマーを作成しました。3分はプログラムで変更できます。実行されるとまず、オンボードのLEDが点滅、PC側のターミナルソフトの起動待ちとなります。PC側でTera Termが起動すると、次にI2Cデバイスのスキャンが実行され、ターミナルソフトに結果が表示されます。正常であればここで、0x27のLCDデバイスが確認できます。この後3分カウントダウンがスタートします。カウントダウンが完了するとブザーがなります。
部品リスト
GROVEの16 x 2 LCD 1 スイッチサイエンス
電子ブザーPKB24SPCH3601 1 秋月電子通商
配線図
ソースリスト
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/i2c.h"
//#define PICO_DEFAULT_LED_PIN 25
#define LED_PIN PICO_DEFAULT_LED_PIN
#define BUZZER_PIN 2
#define I2C_PORT i2c0
#define I2C_SDA 8
#define I2C_SCL 9
// wait stdio start
int WaitTerminalStartup() {
int btnin;
while(true)
{
if(stdio_usb_connected())
{
return 0;
}
gpio_put(LED_PIN, 1);
sleep_ms(200);
gpio_put(LED_PIN, 0);
sleep_ms(200);
}
}
void ScanI2CBus() {
printf("\nI2C Bus Scan\n");
printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
for (int addr = 0; addr < (1 << 7); ++addr) {
if (addr % 16 == 0) {
printf("%02x ", addr);
}
int ret;
uint8_t rxdata;
ret = i2c_read_blocking(I2C_PORT, addr, &rxdata, 1, false);
sleep_ms(10);
printf(ret < 0 ? "." : "@");
printf(addr % 16 == 15 ? "\n" : " ");
}
}
//lcd
//LCDのソースは10.1.章を参照してください
//---
//timer
#define TIMER_MINUTES 3
int main()
{
char buf[128];
stdio_init_all();
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
gpio_init(BUZZER_PIN);
gpio_set_dir(BUZZER_PIN, GPIO_OUT);
gpio_put(PICO_DEFAULT_LED_PIN, 0);
gpio_put(BUZZER_PIN, 0);
i2c_init(I2C_PORT, 400*1000);
gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
gpio_pull_up(I2C_SDA);
gpio_pull_up(I2C_SCL);
WaitTerminalStartup();
printf("\nTerminal connected\n");
ScanI2CBus();
printf("I2C Scan completed\n");
lcd_init();
lcd_clear();
lcd_set_cursor(0, 0);
sprintf(buf, "%1d minutes timer ", TIMER_MINUTES);
lcd_string(buf);
uint32_t t1 = time_us_32();
while(true) {
uint32_t t2 = time_us_32();
uint32_t span = t2 - t1;
if(span > TIMER_MINUTES*60*1000*1000 ) {
lcd_set_cursor(1, 0);
lcd_string("Time over! ");
gpio_put(BUZZER_PIN, 1);
sleep_ms(3000);
gpio_put(BUZZER_PIN, 0);
break;
}
span = TIMER_MINUTES*60*1000*1000 - span;
uint32_t minutes = span/(60*1000*1000);
uint32_t usec = span%(60*1000*1000);
sprintf(buf, " %2d:%6.3f", minutes, (float)(usec/(1000.0f*1000.0f)));
lcd_set_cursor(1, 0);
lcd_string(buf);
sleep_ms(300);
}
while(true) {
lcd_set_cursor(1, 0);
lcd_string("Time over! ");
sleep_ms(500);
lcd_set_cursor(1, 0);
lcd_string(" ");
sleep_ms(500);
}
return 0;
}
10.3.20x4LCD表示ーオンボード温度ロガー
プロジェクト名:Lcd20x4Logger
プロジェクトの概要
GROVEの20 x 4LCDを使用したLCD表示プロジェクトです。I2CでPicoと通信します。I2Cアドレス は0x27固定です。このプロジェクトではPicoの温度センサー12bitADCにより温度を計測し、PicoのRTCリアルタイムクロックによる時刻ともにLCDに表示します。同時にPCターミナルソフトTeraTermに標準出力にします。Tera Termでは、このログをファイル保存できます。ADCは以下の5チャンネルを内蔵しています。
ADC0 GP26
ADC1 GP27
ADC2 GP28
ADC3 Vsys電源電圧
ADC4オンボード温度
ADC、および内蔵RTCを使用する場合、CMakeLists.txtの最後の近くにある以下行に
ADC、およびRTCのライブラリを追加します。
target_link_libraries(Lcd20x4Logger
hardware_i2c hardware_adc hardware_rtc
)
を以下に変更。
target_link_libraries(Lcd20x4Logger
hardware_i2c hardware_adc hardware_rtc
)
Cソースリストヘッダーに以下を追加します。
#include "hardware/adc.h"
#include "hardware/rtc.h"
ADC4からの読み込みデータは以下関数
static uint16_t adc_read (void)
で読み込みます。読み込みデータは12bitであるため、0-4095の値がかえってきます。これをまず電圧に変換します。12bitフルスケールがVref 3.3vであるため、
conversionFactor = 3.3f/(1 << 12);
float tempVolt = (float)adc_read() * conversionFactor;
これを温度に変換します。電圧と温度の関係は27℃、0.706Vが原点で、1℃の勾配が0.001721Vです。以下となります。
float tempC = 27.0f - (tempVolt - 0.706f)/0.001721f;
華氏ではtempF = tempC * 9.0f / 5.0f + 32.0f;
部品リスト
GROVEの20 x 4 LCD 1 スイッチサイエンス
配線図
ソースリスト
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pico/stdlib.h"
#include "pico/util/datetime.h"
#include "hardware/i2c.h"
#include "hardware/adc.h"
#include "hardware/rtc.h"
//#define PICO_DEFAULT_LED_PIN 25
#define LED_PIN PICO_DEFAULT_LED_PIN
#define I2C_PORT i2c0
#define I2C_SDA 8
#define I2C_SCL 9
//10.2章参照
int WaitTerminalStartup()
float ReadAdcTemperature()
//---------------
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);
}
//10.2章参照
//lcd
//-------------
int main()
{
char buf[128];
stdio_init_all();
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
gpio_put(PICO_DEFAULT_LED_PIN, 0);
i2c_init(I2C_PORT, 400*1000);
gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
gpio_pull_up(I2C_SDA);
gpio_pull_up(I2C_SCL);
WaitTerminalStartup();
printf("\nTerminal connected\n");
ScanI2CBus();
printf("I2C Scan completed\n");
lcd_init();
InitAdc();
InitRtc();
datetime_t nowdt;
int premin = -1;
int cury, curx;
int tempCount;
float tempBuf[12];
int i;
tempCount = 0;
while(true) {
rtc_get_datetime(&nowdt);
sprintf(buf, "%4d/%02d/%02d %02d:%02d:%02d", nowdt.year, nowdt.month, nowdt.day, nowdt.hour,nowdt.min, nowdt.sec);
lcd_set_cursor(0, 0);
lcd_string(buf);
if(premin != nowdt.min)
{
float temp = ReadAdcTemperature();
if(tempCount >= 12) {
for(i = 1; i < 12; i++) {
tempBuf[i -1] = tempBuf[i];
}
tempBuf[11] = temp;
} else {
tempBuf[tempCount] = temp;
}
tempCount++;
for(i = 0; i < 12; i++) {
cury = i/4 + 1;
curx = (i%4)*5;
lcd_set_cursor(cury, curx);
if(i >= tempCount ) {
lcd_string(" ");
} else {
sprintf(buf, " %4.1f", tempBuf[i]);
lcd_string(buf);
}
}
printf("%4d/%02d/%02d %02d:%02d:%02d %4.1f C\n",
nowdt.year, nowdt.month, nowdt.day,
nowdt.hour,nowdt.min, nowdt.sec, temp);
}
premin = nowdt.min;
sleep_ms(1000);
}
return 0;
}
起動されると、まずPCターミナルソフトTera Termの起動待ちとなり、次にI2Cスキャンが実行されます。この後、オンボード計測実行の永久ループにはいります。計測は1分毎に実行され、結果は時刻とともに標準出力TeraTermに出力されます。TeraTerm側では、この出力された計測データをログファイルに保存できます。メニューから”ファイル”>”ログ”でログ設定画面を以下開きます。
保存するファイル名を入力後、"保存"ボタンを押します。以降、PicoからTera Termに出力されたメッセージは保存されます。オプションはこのまま、"追記"、"プレーンテキスト"で問題ありません。
Pico側は1行目は現在時刻を表示します。2-4行は、過去12個の計測温度が表示されます。1分間隔ですので、12分前の温度経過を見ることができます。1分ごとに12個データはシフトします。
10.4.20x4LCD(adafruit)表示-時刻アラーム
プロジェクト名:Lcd20x4
プロジェクト概要
Adafruitの20x4キャラクターのLCDのプロジェクトです。このLCD表示器はLCDと制御基板が分離されて、同じ表示制御基板、バックパックで、異なった表示文字数のLCDをコントロールできます。現時点で日本には代理店はないですが、直接購入できます。また今回はUARTでの接続で使用しました。Picoは2つのUART接続は持っています。通通常UART0は標準出力用となっているため、UART1をLCD表示の通信に使用します。LCD表示器のUART接続のロジックレベルは、5Vです。一方、Picoは3.3Vです。このため、レベル変換モジュールBSS138を使用しました。変換なしに直接、接続するとPico側が破損する恐れがあります。PicoのUART接続を検討するときは、相手のロジックレベルに注意してください。このLCD表示器は、バックライトの色をRGBで設定可能で、コントラスト、ブライトネスもソフトで設定できます。接続は以下となります。
LCD 5V Pico 5V
LCD GND Pico GND
LCD Rx Pico UART1-TX(GPIO4)
LCDからの送信はないので、PicoのRXの接続は不要です。
部品リスト
RGB-LCD 20x4 1 adafruit
RGB-LCD 20x4対応バックバック 1 adafruit
3.3V>5Vロジックレベル変換モジュールBSS138 1 秋月電子通商
電子ブザーPKB24SPCH3601 1 秋月電子通商
配線図
ソースリスト
include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "pico/util/datetime.h"
#include "hardware/rtc.h"
//#define PICO_DEFAULT_LED_PIN 25
#define LED_PIN PICO_DEFAULT_LED_PIN
#define BUZZER_PIN 3
//10.2章参照 -------
int WaitTerminalStartup()
//---------------------
typedef struct _alarmset{
int hour;
int min;
int sec;
bool status;
int buzzerCount;
} alarmset;
alarmset Alarm1,Alarm2, Alarm3;
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
};
Alarm1.hour = 10;
Alarm1.min = 26;
Alarm1.sec = 00;
Alarm1.status = false;
Alarm1.buzzerCount = 0;
Alarm2.hour = 12;
Alarm2.min = 00;
Alarm2.sec = 00;
Alarm2.status = false;
Alarm2.buzzerCount = 0;
Alarm3.hour = 21;
Alarm3.min = 00;
Alarm3.sec = 00;
Alarm3.status = false;
Alarm3.buzzerCount = 0;
rtc_init();
rtc_set_datetime(&t);
sleep_ms(1);
}
//lcd -----------------------
#define UART_ID uart1
#define BAUD_RATE 9600
#define UART_TX_PIN 4
#define LCD_WIDTH 20
#define LCD_HEIGHT 4
// basic commands
#define LCD_DISPLAY_ON 0x42
#define LCD_DISPLAY_OFF 0x46
#define LCD_SET_BRIGHTNESS 0x99
#define LCD_SET_CONTRAST 0x50
#define LCD_AUTOSCROLL_ON 0x51
#define LCD_AUTOSCROLL_OFF 0x52
#define LCD_CLEAR_SCREEN 0x58
#define LCD_SET_SPLASH 0x40
// cursor commands
#define LCD_SET_CURSOR_POS 0x47
#define LCD_CURSOR_HOME 0x48
#define LCD_CURSOR_BACK 0x4C
#define LCD_CURSOR_FORWARD 0x4D
#define LCD_UNDERLINE_CURSOR_ON 0x4A
#define LCD_UNDERLINE_CURSOR_OFF 0x4B
#define LCD_BLOCK_CURSOR_ON 0x53
#define LCD_BLOCK_CURSOR_OFF 0x54
// rgb commands
#define LCD_SET_BACKLIGHT_COLOR 0xD0
#define LCD_SET_DISPLAY_SIZE 0xD1
void lcd_write(uint8_t cmd, uint8_t* buf, uint8_t buflen) {
// all commands are prefixed with 0xFE
const uint8_t pre = 0xFE;
uart_write_blocking(UART_ID, &pre, 1);
sleep_ms(10); // give the display some time
uart_write_blocking(UART_ID, &cmd, 1);
sleep_ms(10); // give the display some time
uart_write_blocking(UART_ID, buf, buflen);
sleep_ms(10); // give the display some time
}
void lcd_set_size(uint8_t w, uint8_t h) {
// sets the dimensions of the display
uint8_t buf[] = { w, h };
lcd_write(LCD_SET_DISPLAY_SIZE, buf, 2);
}
void lcd_set_contrast(uint8_t contrast) {
// sets the display contrast
lcd_write(LCD_SET_CONTRAST, &contrast, 1);
}
void lcd_set_brightness(uint8_t brightness) {
// sets the backlight brightness
lcd_write(LCD_SET_BRIGHTNESS, &brightness, 1);
}
void lcd_set_backlight(bool is_on) {
// turn the backlight on (true) or off (false)
if (is_on) {
lcd_write(LCD_DISPLAY_ON, (uint8_t *) 0, 1);
} else {
lcd_write(LCD_DISPLAY_OFF, NULL, 0);
}
}
void lcd_clear() {
// clear the contents of the display
lcd_write(LCD_CLEAR_SCREEN, NULL, 0);
}
void lcd_set_cursor(bool is_on) {
// set is_on to true if we want the blinking block and underline cursor to show
if (is_on) {
lcd_write(LCD_BLOCK_CURSOR_ON, NULL, 0);
lcd_write(LCD_UNDERLINE_CURSOR_ON, NULL, 0);
} else {
lcd_write(LCD_BLOCK_CURSOR_OFF, NULL, 0);
lcd_write(LCD_UNDERLINE_CURSOR_OFF, NULL, 0);
}
}
void lcd_cursor_reset() {
// reset the cursor to (1, 1)
lcd_write(LCD_CURSOR_HOME, NULL, 0);
}
void lcd_set_cursor_position(uint8_t x, uint8_t y) {
//index 1 start
uint8_t buf[] = {x, y };
lcd_write(LCD_SET_CURSOR_POS, buf, 2);
}
void lcd_set_backlight_color(uint8_t r, uint8_t g, uint8_t b) {
// only supported on RGB displays!
uint8_t buf[] = { r, g, b };
lcd_write(LCD_SET_BACKLIGHT_COLOR, buf, 3);
}
void lcd_set_splash() {
uint8_t splash_buf[LCD_WIDTH * LCD_HEIGHT];
for(int i = 0; i < LCD_WIDTH * LCD_HEIGHT; i++) {
splash_buf[i] = ' ';
}
lcd_write(LCD_SET_SPLASH, splash_buf, LCD_WIDTH * LCD_HEIGHT);
}
int main() {
stdio_init_all();
//led buzzer
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
gpio_put(LED_PIN, 0);
gpio_init(BUZZER_PIN);
gpio_set_dir(BUZZER_PIN, GPIO_OUT);
gpio_put(BUZZER_PIN, 0);
//wait pc terminal start
//WaitTerminalStartup();
//printf("\nusb connected\n");
//rtc
InitRtc();
//lcd
uart_init(UART_ID, BAUD_RATE);
uart_set_translate_crlf(UART_ID, false);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
lcd_clear();
lcd_set_size(LCD_WIDTH, LCD_HEIGHT);
lcd_set_backlight(true);
lcd_set_backlight_color(0x00, 0x00, 0xFF);
lcd_set_contrast(220);
lcd_set_brightness(255);
lcd_set_cursor(false);
lcd_cursor_reset();
char buf[128];
datetime_t nowdt;
int prsec = -1;
while(true) {
rtc_get_datetime(&nowdt);
if(prsec != nowdt.sec) {
if((nowdt.hour == 0) && (nowdt.min == 0) && (nowdt.sec == 0)){
Alarm1.status = false;
Alarm1.buzzerCount = 0;
Alarm2.status = false;
Alarm2.buzzerCount = 0;
Alarm2.status = false;
Alarm2.buzzerCount = 0;
}
if(!Alarm1.status){
if((Alarm1.hour == nowdt.hour) && (Alarm1.min == nowdt.min) && (Alarm1.sec == nowdt.sec))
{
Alarm1.status = true;
Alarm1.buzzerCount = 0;
gpio_put(BUZZER_PIN, 1);
}
} else {
if(Alarm1.buzzerCount > 30) {
gpio_put(BUZZER_PIN, 0);
} else {
Alarm1.buzzerCount++;
}
}
if(!Alarm2.status){
if((Alarm2.hour == nowdt.hour) && (Alarm2.min == nowdt.min) && (Alarm2.sec == nowdt.sec))
{
Alarm2.status = true;
Alarm2.buzzerCount = 0;
gpio_put(BUZZER_PIN, 1);
}
} else {
if(Alarm2.buzzerCount > 30) {
gpio_put(BUZZER_PIN, 0);
} else {
Alarm2.buzzerCount++;
}
}
if(!Alarm3.status){
if((Alarm3.hour == nowdt.hour) && (Alarm3.min == nowdt.min) && (Alarm3.sec == nowdt.sec))
{
Alarm3.status = true;
Alarm3.buzzerCount = 0;
gpio_put(BUZZER_PIN, 1);
}
} else {
if(Alarm3.buzzerCount > 30) {
gpio_put(BUZZER_PIN, 0);
} else {
Alarm3.buzzerCount++;
}
}
sprintf(buf, "%4d/%02d/%02d %02d:%02d:%02d", nowdt.year, nowdt.month, nowdt.day, nowdt.hour,nowdt.min, nowdt.sec);
lcd_set_cursor_position(1, 1);
uart_puts(UART_ID, buf);
lcd_set_cursor_position(1, 2);
if(Alarm1.status){
uart_puts(UART_ID, "alarm1 on ");
} else {
uart_puts(UART_ID, "alarm1 off ");
}
sprintf(buf, "%02d:%02d:%02d", Alarm1.hour,Alarm1.min, Alarm1.sec);
lcd_set_cursor_position(12, 2);
uart_puts(UART_ID, buf);
lcd_set_cursor_position(1, 3);
if(Alarm2.status){
uart_puts(UART_ID, "alarm2 on ");
} else {
uart_puts(UART_ID, "alarm2 off ");
}
sprintf(buf, "%02d:%02d:%02d", Alarm2.hour,Alarm2.min, Alarm2.sec);
lcd_set_cursor_position(12, 3);
uart_puts(UART_ID, buf);
lcd_set_cursor_position(1, 4);
if(Alarm3.status){
uart_puts(UART_ID, "alarm3 on ");
} else {
uart_puts(UART_ID, "alarm3 off ");
}
sprintf(buf, "%02d:%02d:%02d", Alarm3.hour,Alarm3.min, Alarm3.sec);
lcd_set_cursor_position(12, 4);
uart_puts(UART_ID, buf);
}
prsec = nowdt.sec;
sleep_ms(100);
}
return 0;
}
コメントをお書きください