Skip to content

Instantly share code, notes, and snippets.

@ksasao
Created December 3, 2022 21:42
Show Gist options
  • Save ksasao/443dfe3524de7dc5509a04711ddb9d21 to your computer and use it in GitHub Desktop.
Save ksasao/443dfe3524de7dc5509a04711ddb9d21 to your computer and use it in GitHub Desktop.
M5Stack用はかりキット(重さユニット付き)https://www.switch-science.com/products/8014 を利用した重量取得のコードです。#OMMF2022 で利用したものです。メディアンフィルタ(中央値フィルタ)を使って、このセンサ特有のスパイク状(とびとびの値)のノイズを除去しています。
#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;
}
#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();
}
#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