Created
December 3, 2022 21:42
-
-
Save ksasao/443dfe3524de7dc5509a04711ddb9d21 to your computer and use it in GitHub Desktop.
M5Stack用はかりキット(重さユニット付き)https://www.switch-science.com/products/8014 を利用した重量取得のコードです。#OMMF2022 で利用したものです。メディアンフィルタ(中央値フィルタ)を使って、このセンサ特有のスパイク状(とびとびの値)のノイズを除去しています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <M5Atom.h> | |
#include "BrownieClient.h" | |
#define PIN_DOUT 32 | |
#define PIN_SLK 26 | |
#define MEDIAN_FILTER_SIZE 10 | |
static char ssid[64] = "your-ssid"; | |
static char pass[64] = "your-password"; | |
static char mqtt[64] = "192.168.xx.xx"; | |
float weight_buffer[MEDIAN_FILTER_SIZE]; | |
long offset = 8664038; | |
float delta = 25605.35; | |
float weight_buf[MEDIAN_FILTER_SIZE]; | |
BrownieClient bc; | |
void setup() { | |
M5.begin(true, false, true); | |
hx711_init(); | |
// bc.setup("Weight", ssid, pass, mqtt); // WiFiが利用できる環境の時 | |
bc.setup("Weight"); // WiFiを利用したくないとき | |
Serial.println(); | |
Serial.print("MQTT Client ID: "); | |
Serial.println(bc.getClientId()); | |
} | |
void loop(){ | |
// read load cell data | |
float sum = 0; | |
for(int i=0; i<MEDIAN_FILTER_SIZE; i++){ | |
weight_buffer[i] = hx711_read(); | |
delay(100); | |
} | |
float weight = torben(weight_buffer, MEDIAN_FILTER_SIZE); | |
// Publish data | |
bc.reconnect(); | |
String topicW = "Weight"; | |
String dataW = "{\"Id\":\"BoogieBoard\",\"Value\":" + String(weight,3) + "}"; | |
bc.publish(topicW,dataW); | |
bc.loop(); | |
M5.update(); | |
} | |
float hx711_read(){ | |
long raw_data = hx711_read_raw(); | |
//Serial.println(raw_data); | |
float weight = (raw_data-offset) / delta; | |
return weight; | |
} | |
void hx711_init(){ | |
pinMode(PIN_SLK, OUTPUT); | |
pinMode(PIN_DOUT, INPUT); | |
digitalWrite(PIN_SLK, HIGH); | |
delayMicroseconds(100); | |
digitalWrite(PIN_SLK, LOW); | |
delayMicroseconds(100); | |
} | |
unsigned long hx711_read_raw(void){ | |
unsigned long data=0; | |
while(digitalRead(PIN_DOUT)!=0); | |
delayMicroseconds(10); | |
for(int i=0;i<24;i++) | |
{ | |
digitalWrite(PIN_SLK,1); | |
delayMicroseconds(5); // 5 | |
digitalWrite(PIN_SLK,0); | |
delayMicroseconds(5); // 5 | |
data = (data<<1)|(digitalRead(PIN_DOUT)); | |
} | |
digitalWrite(PIN_SLK,1); | |
delayMicroseconds(10); // 10 | |
digitalWrite(PIN_SLK,0); | |
delayMicroseconds(10); // 10 | |
return data^0x800000; | |
} | |
/* | |
* The following code is public domain. | |
* Algorithm by Torben Mogensen, implementation by N. Devillard. | |
* This code in public domain. | |
* http://ndevilla.free.fr/median/median/index.html | |
*/ | |
float torben(float m[], int n) | |
{ | |
int i, less, greater, equal; | |
float min, max, guess, maxltguess, mingtguess; | |
min = max = m[0] ; | |
for (i=1 ; i<n ; i++) { | |
if (m[i]<min) min=m[i]; | |
if (m[i]>max) max=m[i]; | |
} | |
while (1) { | |
guess = (min+max)/2; | |
less = 0; greater = 0; equal = 0; | |
maxltguess = min ; | |
mingtguess = max ; | |
for (i=0; i<n; i++) { | |
if (m[i]<guess) { | |
less++; | |
if (m[i]>maxltguess) maxltguess = m[i] ; | |
} else if (m[i]>guess) { | |
greater++; | |
if (m[i]<mingtguess) mingtguess = m[i] ; | |
} else equal++; | |
} | |
if (less <= (n+1)/2 && greater <= (n+1)/2) break ; | |
else if (less>greater) max = maxltguess ; | |
else min = mingtguess; | |
} | |
if (less >= (n+1)/2) return maxltguess; | |
else if (less+equal >= (n+1)/2) return guess; | |
else return mingtguess; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ArduinoUniqueID.h> | |
#include <WiFi.h> | |
#include <PubSubClient.h> | |
#include "BrownieClient.h" | |
typedef enum | |
{ | |
OFF, | |
BOOTING, | |
CONNECTING, | |
CONNECTED, | |
DISCONNECTED, | |
SENDING, | |
RECEIVING, | |
ERROR, | |
SAVING | |
} BROWNIE_STATUS; | |
const char hex[17]="0123456789ABCDEF"; | |
char id[100]; | |
String name; | |
char clientIdChar[50]; | |
bool wifiConnected = false; | |
bool offlineMode = false; | |
#define BROWNIE_CLIENT_BUFFER_SIZE 4096 | |
char msgBuffer[BROWNIE_CLIENT_BUFFER_SIZE]; | |
char topicBuffer[BROWNIE_CLIENT_BUFFER_SIZE]; | |
char* _ssid; | |
char* _password; | |
char* _server; | |
WiFiClient wifiClient; | |
PubSubClient mqttClient(wifiClient); | |
std::function<void(char*, uint8_t*, unsigned int)> receivedCallback; | |
const char mqttUserName[] = ""; | |
const char mqttPass[] = ""; | |
void reConnect(bool toReboot); | |
// private methods | |
#if defined(_M5ATOM_H_) | |
void set_led(uint8_t r, uint8_t g, uint8_t b){ | |
int color = (r << 16) | (g << 8) | b; | |
M5.dis.drawpix(0, color); | |
delay(30); | |
} | |
void blink_led(uint8_t r, uint8_t g, uint8_t b, int duration, int count){ | |
for(int i=0; i< count; i++){ | |
set_led(r,g,b); | |
delay(duration>>1); | |
set_led(0,0,0); | |
delay(duration>>1); | |
} | |
} | |
#endif | |
void setStatus(BROWNIE_STATUS status){ | |
#if defined(_M5ATOM_H_) | |
switch(status){ | |
case OFF: | |
set_led(0,0,0); | |
break; | |
case BOOTING: | |
set_led(255,255,255); | |
break; | |
case CONNECTING: | |
blink_led(255,128,0,500,1); | |
break; | |
case CONNECTED: | |
set_led(0,0,255); | |
break; | |
case DISCONNECTED: | |
blink_led(255,255,0,100,2); | |
break; | |
case SENDING: | |
set_led(0,255,0); | |
break; | |
case RECEIVING: | |
set_led(255,128,0); | |
break; | |
case ERROR: | |
blink_led(255,0,0,100,10); | |
break; | |
case SAVING: | |
break; | |
default: | |
set_led(0,0,0); | |
break; | |
} | |
#else | |
switch(status){ | |
case CONNECTING: | |
delay(500); | |
break; | |
default: | |
break; | |
} | |
#endif | |
} | |
void createClientId(String header){ | |
setStatus(BOOTING); | |
id[UniqueIDsize*2]='\0'; | |
for(size_t i = 0; i < UniqueIDsize; i++){ | |
id[i*2] = hex[UniqueID[i] >> 4]; | |
id[i*2+1] = hex[UniqueID[i] & 0xF]; | |
} | |
name = header; | |
String clientId = name + "-" + String((char*) id); | |
clientId.toCharArray(clientIdChar,clientId.length()+1); | |
} | |
// MQTT Subscribe | |
void callbackHook(char* topic, byte* payload, unsigned int length){ | |
setStatus(RECEIVING); | |
receivedCallback(topic, payload,length); | |
setStatus(CONNECTED); | |
} | |
void mqttSubscribe(String topic, MQTT_CALLBACK_SIGNATURE){ | |
mqttClient.subscribe(topic.c_str(),0); // QOS = 0 | |
receivedCallback = callback; | |
mqttClient.setCallback(callbackHook); | |
} | |
// MQTT Publish | |
void mqttPublish(String topic, String data) { | |
setStatus(SENDING); | |
int length = data.length(); | |
data.toCharArray(msgBuffer,length+1); | |
length = topic.length(); | |
topic.toCharArray(topicBuffer, length+1); | |
if(!offlineMode){ | |
mqttClient.publish(topicBuffer, msgBuffer); | |
} | |
Serial.print(topic); | |
Serial.print(" "); | |
Serial.println(data); | |
setStatus(CONNECTED); | |
} | |
void reboot(){ | |
Serial.println("Rebooting..."); | |
setStatus(BOOTING); | |
delay(5 * 1000); | |
ESP.restart(); | |
} | |
void initWiFi(){ | |
if(offlineMode){ | |
Serial.println("Booting offline mode."); | |
setStatus(CONNECTED); | |
return; | |
} | |
// WiFi connection | |
WiFi.begin(_ssid, _password); | |
int count = 0; | |
wifiConnected = true; | |
while( WiFi.status() != WL_CONNECTED) { | |
Serial.print("."); | |
setStatus(CONNECTING); | |
count++; | |
if(count > 20){ | |
setStatus(ERROR); | |
wifiConnected = false; | |
break; | |
} | |
} | |
if(wifiConnected){ | |
Serial.println("Connected."); | |
// setBufferSize (PubSubClient >= 2.8.0) | |
if(mqttClient.setBufferSize(BROWNIE_CLIENT_BUFFER_SIZE)){ | |
Serial.print("Max send/receive buffer size: "); | |
Serial.println(BROWNIE_CLIENT_BUFFER_SIZE); | |
}else{ | |
Serial.println("BROWNIE_CLIENT_BUFFER_SIZE is too large."); | |
} | |
mqttClient.setServer(_server, 1883); | |
reConnect(false); | |
setStatus(CONNECTED); | |
}else{ | |
Serial.println(); | |
Serial.println("Connection error. Check WiFi settings."); | |
setStatus(DISCONNECTED); | |
Serial.println("Wait for 1 min. to reboot"); | |
delay(60 * 1000); | |
reboot(); | |
} | |
} | |
void reConnect(bool toReboot) { | |
if(offlineMode){ | |
setStatus(CONNECTED); | |
return; | |
} | |
int resetCounter = 0; | |
while (!mqttClient.connected()) { | |
setStatus(CONNECTING); | |
Serial.print("Attempting MQTT connection..."); | |
if (mqttClient.connect(clientIdChar,mqttUserName,mqttPass)) { | |
Serial.print("Connected with Client ID: "); | |
Serial.print(clientIdChar); | |
Serial.print(", Username: "); | |
Serial.print(mqttUserName); | |
Serial.print(" , Passwword: "); | |
int i=0; | |
while(mqttPass[i++]!='\0'){ | |
Serial.print("*"); | |
} | |
} | |
else { | |
setStatus(ERROR); | |
// http://pubsubclient.knolleary.net/api.html#state | |
Serial.print("failed, state="); | |
Serial.println(mqttClient.state()); | |
Serial.println("try again in 5 seconds"); | |
delay(5000); | |
} | |
if(resetCounter++ >= 10){ | |
if(toReboot){ | |
reboot(); | |
}else{ | |
wifiConnected = false; | |
return; | |
} | |
} | |
} | |
setStatus(CONNECTED); | |
} | |
// public methods | |
BrownieClient::BrownieClient() | |
{ | |
} | |
void BrownieClient::setup(String name) | |
{ | |
createClientId(name); | |
offlineMode = true; | |
initWiFi(); | |
} | |
void BrownieClient::setup(String name, char* ssid, char* password, char* server) | |
{ | |
_ssid = ssid; | |
_password = password; | |
_server = server; | |
createClientId(name); | |
initWiFi(); | |
} | |
String BrownieClient::getName(void) | |
{ | |
return name; | |
} | |
char* BrownieClient::getClientId(void) | |
{ | |
return clientIdChar; | |
} | |
void BrownieClient::reconnect(void){ | |
if(offlineMode){ | |
return; | |
} | |
if(!wifiConnected){ | |
return; | |
} | |
reConnect(true); | |
mqttClient.loop(); | |
} | |
void BrownieClient::publish(String topic, String body){ | |
if(offlineMode){ | |
mqttPublish(topic,body); | |
return; | |
} | |
if(!wifiConnected){ | |
setStatus(DISCONNECTED); | |
return; | |
} | |
reConnect(true); | |
mqttPublish(topic,body); | |
} | |
void BrownieClient::subscribe(String topic, MQTT_CALLBACK_SIGNATURE){ | |
mqttSubscribe(topic, callback); | |
} | |
void BrownieClient::reboot(void){ | |
reboot(); | |
} | |
void BrownieClient::loop(){ | |
mqttClient.loop(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __BROWNIE_CLIENT_H__ | |
#define __BROWNIE_CLIENT_H__ | |
//#include <M5Stack.h> | |
//#include <M5StickC.h> | |
#include <M5Atom.h> | |
#define USE_BROWNIE_LED | |
#include <PubSubClient.h> | |
class BrownieClient { | |
private: | |
public: | |
BrownieClient(); | |
String getName(); | |
char* getClientId(); | |
void setup(String name, char* ssid, char* password, char* server); | |
void setup(String name); | |
void reconnect(void); | |
void publish(String topic, String body); | |
void subscribe(String topic, MQTT_CALLBACK_SIGNATURE); | |
void reboot(); | |
void loop(); | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment