@tom2020
I am giving below the source code for the .py and .ino files of your app. Interested readers my get involved, read it and debate if there are something that deos not match between the .py and .ino files, working principle, etc.
Sketch.ino
#include "Arduino_RouterBridge.h"
#define NUM_BTNS 8
int pins[] = {4, 5, 6, 7, 8, 9, 11, 12};
int pinStates[] = {0, 0, 0, 0, 0, 0, 0, 0};
String read_buttons() {
String payload = "{";
for (int i = 0; i < NUM_BTNS; i++) {
payload += "\"btn" + String(i + 1) + "\":" + String(pinStates[i]);
if (i < NUM_BTNS - 1) payload += ",";
}
payload += "}";
return payload;
}
void set_pin(String args) {
int comma = args.indexOf(",");
String btn = args.substring(0, comma);
int val = args.substring(comma + 1).toInt();
int idx = btn.substring(3).toInt() - 1;
if (idx >= 0 && idx < NUM_BTNS) {
digitalWrite(pins[idx], val);
pinStates[idx] = val;
}
}
bool linux_started() { return true; }
void setup() {
Bridge.begin();
for (int i = 0; i < NUM_BTNS; i++) {
pinMode(pins[i], OUTPUT);
digitalWrite(pins[i], LOW);
}
Bridge.provide("set_pin", set_pin);
Bridge.provide("linux_started", linux_started);
bool started = false;
while (!started) {
Bridge.call("linux_started").result(started);
}
}
void loop() {
Bridge.notify("payload", read_buttons());
delay(500);
}
main.py
from arduino.app_utils import App, Bridge
from arduino.app_bricks.web_ui import WebUI
import time
import threading
import json
import os
ui = WebUI()
def pin_callback(data):
print("pins:", data)
ui.send_message("payload", data)
def set_pin_handler(client_id, data):
pin_key = data.get("pin")
val = int(data.get("value", 0))
print("set_pin:", pin_key, "->", val)
Bridge.call("set_pin", pin_key + "," + str(val))
def get_sysinfo():
info = {}
try:
with open("/proc/stat") as f:
a = f.readline().split()[1:]
time.sleep(0.2)
with open("/proc/stat") as f:
b = f.readline().split()[1:]
idle = int(b[3]) - int(a[3])
total = sum(int(x) for x in b) - sum(int(x) for x in a)
info["cpu"] = round(100.0 * (1 - idle/total), 1) if total else 0
except:
info["cpu"] = 0
try:
d = {}
with open("/proc/meminfo") as f:
for line in f:
p = line.split()
d[p[0].rstrip(":")] = int(p[1])
total = d["MemTotal"]
free = d.get("MemAvailable", d.get("MemFree", 0))
used = total - free
info["mem_pct"] = round(100.0 * used / total, 1)
info["mem_used"] = round(used / 1024**2, 2)
info["mem_total"] = round(total / 1024**2, 2)
except:
info["mem_pct"] = info["mem_used"] = info["mem_total"] = 0
try:
st = os.statvfs("/")
total = st.f_blocks * st.f_frsize
free = st.f_bavail * st.f_frsize
used = total - free
info["disk_pct"] = round(100.0 * used / total, 1)
info["disk_used"] = round(used / 1024**3, 2)
info["disk_total"] = round(total / 1024**3, 2)
except:
info["disk_pct"] = info["disk_used"] = info["disk_total"] = 0
try:
with open("/proc/uptime") as f:
secs = float(f.readline().split()[0])
h, r = divmod(int(secs), 3600)
m, s = divmod(r, 60)
info["uptime"] = "{:02d}:{:02d}:{:02d}".format(h, m, s)
except:
info["uptime"] = "00:00:00"
return info
def sysinfo_loop():
while True:
try:
ui.send_message("sysinfo", json.dumps(get_sysinfo()))
except Exception as e:
print("sysinfo error:", e)
time.sleep(3)
ui.on_message("set_pin", set_pin_handler)
Bridge.provide("payload", pin_callback)
threading.Thread(target=sysinfo_loop, daemon=True).start()
App.run()
Qustion-1:
If the purpose of the following code at the sketch side is to wait until the Linux has started, then there should be a correspondingg Bridge.provide("linux_started", linuxStarted) function in the python script; unfortunately, I can't trace it? Will you help to find it there?
while (!started) {
Bridge.call("linux_started").result(started);
}
These are the code that I use for the above purpose.
At MCU side:
String value = ""; //value is updated by Linux at MPU
bool success = false;
// Wait until Linux is started
do
{
RpcCall rpc = Bridge.call("linux_started");
success = rpc.result(value);
}
while(success != true); //true = 1 or false = 0, value = any value comes from MPU
Monitor.println(value); //shows: Linux has booted...!
At MPU side:
#used only for sync purposes
def linuxStarted():
return "Linux has booted...!" # goes to MCU
Bridge.provide("linux_started", linuxStarted)