hiro yamamoto works

ESP8266 Web logger
RaspberryPi HiRes Audio
Mini Solar power system
当ブログ掲載内容は無保証です。利用は自己責任でお願いいたします。

 

カレンダー

2021
October
Sun Mon Tue Wed Thu Fri Sat
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            

QRコード

検索



このブログを検索

カウンター

本日のアクセス
昨日のアクセス
総アクセス数

ブログサービス

Powered by

teacup.ブログ
RSS

シリンダ移動時間測定器(完)

最終版スケッチ

センサ1だけを使って往復合計時間を測定するモードを
追加しました。
切換えはクリアスイッチを押しながら電源をいれ、約2秒
後に離すことでできるようにしました。

気になる点
スケッチ実行速度が測定値にどのくらい影響するか
わからない。

クリックすると元のサイズで表示します
通常測定
シリンダセンサをシリンダの両ストロークエンドに取り付け
ONすることを確認します。測定前はどちらかのセンサが
ONしている状態にします。クリアを押してからシリンダを
動作させて測定します。
Push、Pull時間を表示します。
クリックすると元のサイズで表示します

1センサ往復測定
クリアスイッチを押しながら電源をいれ、約2秒
後に離す。
センサ1取り付け位置は通常測定と同様(センサ2有無不問)
測定前はセンサ1がONしている状態にします。
クリアを押してからシリンダを動作させて測定します。
時間を表示します。
クリックすると元のサイズで表示します


クリックすると元のサイズで表示します
ターミナルブロックに自作センサと電源を接続

クリックすると元のサイズで表示します
電源スイッチと表示クリアスイッチ

稚拙スケッチの紹介
注意 コピペ後#includeの後の不等号を半角に直します。
   コメント表現の揺れあります。
/*
millis()約50日でオーバーフローは考慮しない
PORTBは、Arduinoのデジタルピンの8番から13番に対応する。
ポートBをすべて入力
D8(sensor0) アクチェータの出(push)側端
D9(sensor1) アクチェータの戻り(pull)側端
Bit0,1(D8,9)入力はプルアップすること。active LOW*/
#include
#include

LiquidCrystal_PCF8574 lcd(0x27); // set the LCD address to 0x27 for a 16 chars and 2 line display

uint8_t buttonState = 0;
uint8_t lastButtonState = 0;
unsigned long pushStartTime = 0;
unsigned long pushEndTime = 0;
unsigned long pushTime = 0;
unsigned long pullStartTime = 0;
unsigned long pullEndTime = 0;
unsigned long pullTime = 0;
unsigned long PP_Time = 0;
const uint8_t clearPBS = 2;//測定値クリアプッシュスイッチ
bool PPMode = false;

void setup() {
//Serial.begin(115200);
Wire.begin();
//Wire.setClock(100000);//400kHzでも動きそうだが(デフォルトは100kHz 100000)
pinMode(clearPBS, INPUT_PULLUP);//測定値クリアボタンスイッチ
DDRB = B00000000; // ポートBをすべて入力
//
//電源投入時に測定値クリアボタンスイッチHIGHなら従来通りPush-Pull測定モード
//LOWだったら、往復測定モードとする。
//
lcd.setBacklight(1);
if (digitalRead(clearPBS) == LOW) {
//フラグを立てる
PPMode = true;
//Push-Pull Modeのlcd初期表示
lcd.begin(16, 2); // initialize the lcd
lcd.clear();//
lcd.setCursor(0, 0); lcd.print("Push-Pull(Sen1)");
lcd.setCursor(5, 1); lcd.print(PP_Time);
lcd.setCursor(14, 1); lcd.print("mS");

} else {

lcd.begin(16, 2); // initialize the lcd
lcd.clear();//
lcd.setCursor(0, 0); lcd.print("Push ");
lcd.setCursor(5, 0); lcd.print(pushTime);
lcd.setCursor(14, 0); lcd.print("mS");
lcd.setCursor(0, 1); lcd.print("Pull ");
lcd.setCursor(5, 1); lcd.print(pullTime);
lcd.setCursor(14, 1); lcd.print("mS");
}
}

void loop() {

/*B PORT入力ピンレジスタの下位2Bitだけ(D8,D9)使う
入力との論理積を取ることで必要以外bitの影響を受けないようにする & 0x03 00000011
*/
if (PPMode == false) {
buttonState = PINB & 0x03; // D8:PortB Bit0 D9 Bit1 磁気検出ON = L

//D9,D8どちらかがLOWになったときから始める
if (buttonState != lastButtonState) {//以前と現在が違う時

/*D9pull端戻り限ONの時LOW,D8push端出限ONの時LOW PORT Bのbit0がD8,bit1がD9*/
/*現在D9H,D8H(移動中) && 以前D9L(pull端戻り限ON),D8H*/
if ((buttonState == 0x03) && (lastButtonState == 0x01)) {
pushStartTime = millis(); //戻り限から出発した時間を変数に記録
/*現在D9H,D8L(push端出限ON) && 以前D9H,D8H(移動中)*/
} else if ((buttonState == 0x02) && (lastButtonState == 0x03)) {
/*出限到着時間 - 戻り限出発時間 = 戻り〜出移動時間 変数へ記録*/
pushEndTime = millis();
pushTime = pushEndTime - pushStartTime;//移動中H,Hから到着H,L(D8push端出限)
lcd.setCursor(5, 0); lcd.print(" ");
lcd.setCursor(5, 0); lcd.print(pushTime);
/*現在D9H,D8H(出限から戻り限へ移動中) && 以前D9H(pull端戻り限OFF)D8L(push端出限ON)*/
} else if ((buttonState == 0x03) && (lastButtonState == 0x02)) {
pullStartTime = millis();//出限を出発した時間を変数に記録
/*現在D9L(pull端戻り限ON),D8H(push端出限OFF) && 以前D9H,D8H(出限から戻り限へ移動中)*/
} else if ((buttonState == 0x01) && (lastButtonState == 0x03)) {
/*戻り限到着時間(現在時間) - 出限出発時間 = 出〜戻り移動時間 変数へ記録*/
pullEndTime = millis();
pullTime = pullEndTime - pullStartTime;
lcd.setCursor(5, 1); lcd.print(" ");
lcd.setCursor(5, 1); lcd.print(pullTime);
}
/*clearBPSが押されて変数は0になっても、millis()カウントは電源投入から進んでいるので
clearBPS使い方 sensor1,2のいずれかがONする位置で押して下さい。sensor1,2両方がOFF状態で
押すと、アクチェータを移動してsensor1,2のいずれかがONした時に、数値が表示されてしまいます。
再度clearBPを押すと数値がクリアされ測定できます。 */
}
lastButtonState = buttonState;
if (digitalRead(clearPBS) == LOW) {//20210904>
buttonState = 0;
lastButtonState = 0;
pushStartTime = 0;
pushEndTime = 0;
pushTime = 0;
pullStartTime = 0;
pullEndTime = 0;
pullTime = 0;
PP_Time = 0;
lcd.clear();//LCDに表示されている情報を消す
delay(100);
lcd.setCursor(0, 0); lcd.print("Push ");
lcd.setCursor(5, 0); lcd.print(pushTime);
lcd.setCursor(14, 0); lcd.print("mS");
lcd.setCursor(0, 1); lcd.print("Pull ");
lcd.setCursor(5, 1); lcd.print(pullTime);
lcd.setCursor(14, 1); lcd.print("mS");
}
} else {
buttonState = PINB & 0x03; // D8:PortB Bit0 D9 Bit1 磁気検出ON = L

//D9,D8どちらかがLOWになったときから始める
if (buttonState != lastButtonState) {//以前と現在が違う時

/*D9pull端戻り限ONの時LOW,D8push端出限ONの時LOW PORT Bのbit0がD8,bit1がD9*/
/*現在D9H,D8H(移動中) && 以前D9L(pull端戻り限ON),D8H*/
if ((buttonState == 0x03) && (lastButtonState == 0x01)) {
pushStartTime = millis(); //戻り限から出発した時間を変数に記録

} else if ((buttonState == 0x01) && (lastButtonState == 0x03)) {
/*戻り限到着時間(現在時間) - 出限出発時間 = 出〜戻り移動時間 変数へ記録*/
pullEndTime = millis();
PP_Time = pullEndTime - pushStartTime;//1センサで往復時間を測定
lcd.setCursor(5, 1); lcd.print(" ");
lcd.setCursor(5, 1); lcd.print(PP_Time);
}
/*clearBPSが押されて変数は0になっても、millis()カウントは電源投入から進んでいるので
clearBPS使い方 sensor1,2のいずれかがONする位置で押して下さい。sensor1,2両方がOFF状態で
押すと、アクチェータを移動してsensor1,2のいずれかがONした時に、数値が表示されてしまいます。
再度clearBPを押すと数値がクリアされ測定できます。*/
}
lastButtonState = buttonState;
if (digitalRead(clearPBS) == LOW) {
buttonState = 0;
lastButtonState = 0;
pushStartTime = 0;
pushEndTime = 0;
pushTime = 0;
pullStartTime = 0;
pullEndTime = 0;
pullTime = 0;
PP_Time = 0;
lcd.clear();//LCDに表示されている情報を消す
delay(100);
lcd.setCursor(0, 0); lcd.print("Push-Pull(Sen1)");
lcd.setCursor(5, 1); lcd.print(PP_Time);
lcd.setCursor(14, 1); lcd.print("mS");
}
} //PPMode == true
}
0
投稿者:管理人

NTPで取得した時刻をRTCへセットする(ESP32)

ESP-WROOM-32でやってみました。
調査結果により書き直したので、記事タイトルと内容に
ズレがあります。

調べてわかったこと

起動時のNTP時刻取得後は、1時間毎のgetLocalTime()時に
NTP時刻同期していました。
よって、提供される時刻の精度は問題ないと思われます。
つまり、NTP又はネットワーク内タイムサーバに接続できる
環境なら、RTCモジュール追加の必要はない?
かもしれません。タイムサーバ接続不可能な環境で使うなら
RTCは有ったほうが良いと思います。

getLocalTime()
ローカル時刻を取得する。
失敗時10ms毎に取得繰返し5000mS(デフォルト)でタイムアウト
取得成功でtrue返す。失敗でfalse返す。
例 getLocalTime(&timeinfo, 5000)

getLocalTime()後のsntp_get_sync_statusをシリアルモニタ
表示してみた。
クリックすると元のサイズで表示します
前半 10分間隔 後半 11分間隔でgetLocalTime()してます。
約60分毎に sntp_get_sync_status = COMPLETED とあります。

スケッチ例 「SimpleTime」で実験中
(ESP32 Dev Module用のスケッチ例 ESP32→TIME→SimpleTime)

コメントとテストを追記したスケッチ(手直し中)
WiFi.disconnect(true);とWiFi.mode(WIFI_OFF);の2行は
接続を継続するため無効にしました。
include行は < から < へ修正して下さい。
#include <WiFi.h>
#include "time.h"

const char* ssid = "my-ssid";
const char* password = "my-password";

const char* ntpServer = "pool.ntp.org"; // NTPサーバ,IP Address指定できるか?
const long gmtOffset_sec = 9 * 3600; // 時差を秒で設定・・・9時間
const int daylightOffset_sec = 0; // サマータイム設定・・・0

void printLocalTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo, 5000)) {
// コメント追記 タイムアウトデフォルト5000mS
Serial.println("Failed to obtain time");
return;
}
//追記 NTP同期確認のため ・・・COMPLETEDで同期完了と思う
if (sntp_get_sync_status() == SNTP_SYNC_STATUS_COMPLETED) {
Serial.println("sntp_get_sync_status = COMPLETED");
Serial.println(&timeinfo, "%A, %B %m %d %Y %H:%M:%S");
// コメント追記 A 曜日英語表記,B 月英語表記,m 月の数字,d 日,Y 年,H時:M分:S秒
}
}
void setup() {
Serial.begin(115200);

//connect to WiFi
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");

//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();

//disconnect WiFi as it's no longer needed
//WiFi.disconnect(true); //無効にしました
//WiFi.mode(WIFI_OFF); // 無効にしました
}

void loop() {
//delay(1000); // 無効にしました
printLocalTime();
delay(660000); // 追記しました
}

(スケッチ例を公開している方々に感謝します。)

RTC時刻合わせするスケッチもよかったらどうぞ
#include <WiFi.h>
#include "time.h"
#include <Wire.h>
#include <RTClib.h>

const char* ssid = "my-ssid";
const char* password = "my-password";

const char* ntpServer = "pool.ntp.org"; // pool.ntp.org
const long gmtOffset_sec = 9 * 3600; // 時差を秒で設定・・・9時間
const int daylightOffset_sec = 0; // サマータイム設定・・・0

unsigned long interval_t = 60000 * 61 * 1; // 60000(mS)*60*1=1h 60000(1min)
unsigned long previousMillis_t = 0;
unsigned long previous_t = 0;

char date_ymdhms[21]; // yyyy/mm/dd,hh:mm:ssn0

RTC_DS3231 rtc;//select use RTC DS3231

void printLocalTime() {
//sntp_get_sync_status()は時間同期のステータスを取得します。
//更新が完了すると、ステータスはSNTP_SYNC_STATUS_COMPLETEDとして返されます。
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
if (sntp_get_sync_status() == SNTP_SYNC_STATUS_COMPLETED) {
Serial.println("sntp_get_sync_status = COMPLETED");
Serial.println(&timeinfo, "%A, %B %m %d %Y %H:%M:%S");
}
}

void setup() {
Serial.begin(115200);
Wire.begin();

//connect to WiFi
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");

//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime(); // NTP時刻取得、同期ステータス表示、システム時刻表示

if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
}
// RTCが電源を失った時(電池切れ)getLocalTime()して取得成功の場合取得時刻をRTCにセットし、
// 失敗の場合コンパイル時刻をRTCにセットする。
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
struct tm timeInfo;
if (!getLocalTime(&timeInfo)) {
/* 失敗でメッセージを表示しコンパイル時刻をRTCへセット 取得成功で取得時刻をRTCへセット */
Serial.println("Failed to obtain time Set to compile time"); // 時間の取得に失敗しましたコンパイル時刻をセットします
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // コンパイル日時を仮設定
DateTime now = rtc.now();
sprintf(date_ymdhms, "%04d/%02d/%02d,%02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
Serial.println(date_ymdhms);
} else {
rtc.adjust(DateTime(timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday,
timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec));
//tm_year:1900年からの年数 tm_mon:1月からの月数
Serial.println("adjust RTC !!");
DateTime now = rtc.now();
sprintf(date_ymdhms, "%04d/%02d/%02d,%02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
Serial.println(date_ymdhms);
}
}
//disconnect WiFi as it's no longer needed
//WiFi.disconnect(true);
//WiFi.mode(WIFI_OFF);
}
void loop() {
// 定期的にgetLocalTime()して同期できたらRTCをセットする
unsigned long currentMillis_t = millis();
if (currentMillis_t - previousMillis_t >= interval_t) { //interval_t 61分はOK60分はNG
previousMillis_t = currentMillis_t;
struct tm timeInfo;
if (getLocalTime(&timeInfo)) {
if (sntp_get_sync_status() == SNTP_SYNC_STATUS_COMPLETED) {
rtc.adjust(DateTime(timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday,
timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec));
//tm_year:1900年からの年数 tm_mon:1月からの月数
Serial.println("adjust RTC !!");
} // else { Serial.println("NOT COMPLET"); }
} else {
Serial.println("Failed to obtain time");
}
}
//delay(1000);
// 10分毎にRTC時刻を取得して表示する。
unsigned long interval = 60000 * 10 *1; // 60000(1min)
unsigned long current_t = millis();
if (current_t - previous_t >= interval) {
previous_t = current_t;
//printLocalTime(); // このスケッチオリジナルの関数
DateTime now = rtc.now();
sprintf(date_ymdhms, "%04d/%02d/%02d,%02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
Serial.println(date_ymdhms);
}
}

(スケッチ例を公開している方々に感謝します。)
無保証自己責任でよろしくおねがいします。
0
タグ: ESP32_Arduino
投稿者:管理人
1 2 3 4 | 《前のページ | 次のページ》
/4 
 
AutoPage最新お知らせ