質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

解決済

3回答

2749閲覧

【Arduino】LCDディスプレイの表示がLoop()でおかしくなってしまう

reud

総合スコア21

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2018/03/04 07:07

前提・実現したいこと

ArdinoでNTPから時間を習得し、LCDに表示させたいです。

発生している問題・エラーメッセージ

Setup関数では適切に表示されるのに、Loop関数では表示がおかしくなってしまう

該当のソースコード

C++

1#include <Time.h> 2#include <TimeLib.h> 3 4#include <SPI.h> 5#include <Ethernet.h> 6#include <EthernetUdp.h> 7#include <LiquidCrystal.h> 8 9 10// MACアドレス 11byte mac[] = { 12 0x00, 0x50, 0xc2, 0x97, 0x22, 0xc3 }; 13 14// UDPローカルポート番号 15unsigned int localPort = 8888; 16 17// NTPタイムサーバIPアドレス(ntp.nict.jp NTP server) 18IPAddress timeServer(133, 243, 238, 164); 19 20// NTPパケットバッファサイズ 21const int NTP_PACKET_SIZE= 48; 22 23// NTP送受信用パケットバッファ 24byte packetBuffer[NTP_PACKET_SIZE]; 25 26// Udpクラス 27EthernetUDP Udp; 28 29// 最後にパケットを送信した時間(ミリ秒) 30unsigned long lastSendPacketTime = 0; 31 32// キャラクタLCDクラス(RS=>7, E=>6, D4=>5, D5=>4, D4=>3, D3=>2) 33LiquidCrystal lcd( 4, 6, 10, 11, 12, 13 ); 34 35void setup() 36{ 37 Serial.begin(115200); 38 Serial.println("Attempting to obtain a DHCP lease..."); 39 40 lcd.begin(16,2); 41 lcd.clear(); 42 43 lcd.print("Starts sync..."); 44 lcd.setCursor(3,1); 45 lcd.print("I'm Arduino"); 46 delay(1000); 47 lcd.clear(); 48 lcd.print("starting... 3"); 49 delay(1000); 50 lcd.setCursor(12,0); 51 lcd.print("2"); 52 delay(1000); 53 lcd.setCursor(12,0); 54 lcd.print("1"); 55 delay(1000); 56 if ( Ethernet.begin(mac) == 0 ) { 57 Serial.println("Failed to configure Ethernet using DHCP"); 58 for(;;) 59 ; 60 } 61 62 Serial.println("A DHCP lease has been obtained."); 63 64 Serial.print("My IP address is "); 65 Serial.println(Ethernet.localIP()); 66 67 Serial.print("Gateway IP address is "); 68 Serial.println(Ethernet.gatewayIP()); 69 70 Serial.print("DNS IP address is "); 71 Serial.println(Ethernet.dnsServerIP()); 72 Serial.println(); 73 74 Udp.begin(localPort); 75 76 // 最初の時刻リクエストを送信 77 sendNTPpacket(timeServer); 78 lastSendPacketTime = millis(); 79} 80 81void loop() 82{ 83 if ( millis() - lastSendPacketTime > 180000 ){ 84 // NTPサーバへ時刻リクエストを送信 85 sendNTPpacket(timeServer); 86 // 時間を更新 87 lastSendPacketTime = millis(); 88 } 89 90 // NTPサーバからのパケット受信 91 if ( Udp.parsePacket() ) { 92 // バッファに受信データを読み込む 93 Udp.read(packetBuffer, NTP_PACKET_SIZE); 94 95 // 時刻情報はパケットの40バイト目からはじまる4バイトのデータ 96 unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); 97 unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); 98 99 // NTPタイムスタンプは64ビットの符号無し固定小数点数(整数部32ビット、小数部32ビット) 100 // 1900年1月1日0時との相対的な差を秒単位で表している 101 // 小数部は切り捨てて、秒を求めている 102 unsigned long secsSince1900 = highWord << 16 | lowWord; 103 Serial.print("Seconds since Jan 1 1900 = " ); 104 Serial.println(secsSince1900); 105 106 // NTPタイムスタンプをUNIXタイムに変換する 107 // UNITタイムは1970年1月1日0時からはじまる 108 // 1900年から1970年の70年を秒で表すと2208988800秒になる 109 const unsigned long seventyYears = 2208988800UL; 110 // NTPタイムスタンプから70年分の秒を引くとUNIXタイムが得られる 111 unsigned long epoch = secsSince1900 - seventyYears; 112 Serial.print("Unix time = "); 113 Serial.println(epoch); 114 115 // Timeライブラリに時間を設定(UNIXタイム) 116 // 日本標準時にあわせるために+9時間しておく 117 setTime(epoch + (9 * 60 * 60)); 118 String s=String(year()); 119 //String s2=hour()+":"+minute()+":"+second(); 120 Serial.print("JST is "); 121 Serial.print(year()); 122 Serial.print('/'); 123 Serial.print(month()); 124 Serial.print('/'); 125 Serial.print(day()); 126 Serial.print(' '); 127 Serial.print(hour()); 128 Serial.print(':'); 129 Serial.print(minute()); 130 Serial.print(':'); 131 Serial.println(second()); 132 Serial.println(); 133 134 // LCDクリア 135 lcd.clear(); 136 lcd.setCursor(0,0); 137 // 年/月/日を表示 138 //lcd.clear(); 139 lcd.print("looping!"); 140 Serial.println(s+"]printing..."); 141 lcd.setCursor(1,1); 142 //lcd.print(s2); 143 // Serial.println(s2+"]printing..."); 144 /* lcd.write('/'); 145 lcd.write(month()); 146 lcd.write('/'); 147 lcd.write(day()); 148 // 2行目3文字目にカーソルを移動 149 lcd.setCursor(3,1); 150 // 時:分:秒を表示 151 lcd.write(hour()); 152 lcd.write(':'); 153 lcd.write(minute()); 154 lcd.write(':'); 155 lcd.write(second()); 156 */ 157 } 158} 159 160// send an NTP request to the time server at the given address 161unsigned long sendNTPpacket(IPAddress& address) 162{ 163 // set all bytes in the buffer to 0 164 memset(packetBuffer, 0, NTP_PACKET_SIZE); 165 // Initialize values needed to form NTP request 166 // (see URL above for details on the packets) 167 packetBuffer[0] = 0b11100011; // LI, Version, Mode 168 packetBuffer[1] = 0; // Stratum, or type of clock 169 packetBuffer[2] = 6; // Polling Interval 170 packetBuffer[3] = 0xEC; // Peer Clock Precision 171 // 8 bytes of zero for Root Delay & Root Dispersion 172 packetBuffer[12] = 49; 173 packetBuffer[13] = 0x4E; 174 packetBuffer[14] = 49; 175 packetBuffer[15] = 52; 176 // all NTP fields have been given values, now 177 // you can send a packet requesting a timestamp: 178 // NTP requests are to port 123 179 Udp.beginPacket(address, 123); 180 Udp.write(packetBuffer, NTP_PACKET_SIZE); 181 Udp.endPacket(); 182}

試したこと

loop関数内において様々な文字の表示を試行→すべてうまく表示されない
Setup関数内に様々な文字を表示させてみた→すべて成功
clear,setCursorもすべてsetup内では正常に動作。Loopではうまく動作されず。
Serialでの表示内容はすべて正常です
[loop関数内でのLCDの状態]https://imgur.com/a/eoWf5.jpg
loop関数でのLCDの状態(別角度)https://youtu.be/rV36PQ88GCQ

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

Ethernet Shield 2ってやつをお使いですか?

スイッチサイエンスのサイト
https://www.switch-science.com/catalog/2270/
から辿った回路図を見ると、少なくとも10番pinはEthernet Shield 2で使用しています。
一方、
LiquidCrystal lcd( 4, 6, 10, 11, 12, 13 );
として10pinをLCDの制御に割り当ててもいます。

ざっとプログラムを眺めた範囲では直接の競合はないようには見えますが、特にEthernetライブラリ中で割り込みを使っていたりするとどうなるかわかりません。
少なくとも、Ethernetを起動したら以降LCDの表示がおかしくなる、という現象には合致するように思えます。

とりあえず(他のピンも含めて)ハード的な競合を確認し、必要に応じて割当を変えてみてはいかがでしょうか。

投稿2018/03/18 06:01

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

setup関数では、lcd.begin、lcd.clear、lcd.printという順序(初期化、画面消去、画面表示)が守られているのに、loop関数にはlcd.beginが抜けています。

lcd.beginをlcd.clearの上に挿入してみては如何でしょうか?

==
せっかくurlを記載していただきましたが、参考になりませんでした。

loop関数内でのLCDの状態]https://imgur.com/a/eoWf5.jpg
404 Not Foundとなりました。

loop関数でのLCDの状態(別角度)https://youtu.be/rV36PQ88GCQ
液晶ディスプレイらしきものが移っていますが、表示内容が確認できるほど鮮明ではありませんでした。

投稿2018/03/04 08:33

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Arduino のことはよく知らないですが、その loop関数というのは繰り返し実行されるものですか?
それなら、あまりに早く繰り返し実行されるために表示がおかしくなるものと推察されます。
ウェイトの関数を挿入するなりして、例えば一秒ごとの実行となるようにしてみてはどうでしょうか。

投稿2018/03/04 07:33

y_waiwai

総合スコア87749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

reud

2018/03/04 07:55

回答ありがとうございます if ( millis() - lastSendPacketTime > 180000 ){ // NTPサーバへ時刻リクエストを送信 sendNTPpacket(timeServer); // 時間を更新 lastSendPacketTime = millis(); } // NTPサーバからのパケット受信 if ( Udp.parsePacket() ) { 辺りの部分でNTPサーバーから情報を習得していないときはlcdへの書き込みが行われない(=三分ごとに書き込みを行う)プログラムなので、繰り返しが早すぎることはないと考えられます。
y_waiwai

2018/03/04 07:58

なら、lcd.print 関数がおかしいということになりますね。ソースが提示されてないので具体的なところはわかりませんが。
reud

2018/03/04 08:06

LiquidCrystal.hがおかしいのならば、setup関数でLCDの表示がおかしくなっているはずなので、その可能性は低いと考えられます。 ソースはArudinoに最初から付いてるライブラリですので省略させていただきます。申し訳ございません。
y_waiwai

2018/03/04 08:12

デバッグする場面において、XXXは間違っていない、と断定してしまうのは解決から遠ざかるだけです。 ライブラリだろうとなんだろうと、他人の作ったコードは、その作った人が想定する使い方で、想定するデータを入れて初めて正しく動作する(であろう)ものでしかありません。 いかな仮定、前提を設けようとも、あなたが提示したコード以外のところに動作不良の原因があるのは間違いなさそうですが
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問