Category Archives: IOT / Domoticz

Harp with leds

A ledstrip on a Harp, now I can see the strings at night!

Woohoo .. ( Little harp in the background (autoharp))

Well .. its a pity that the distance of the leds is NOT the same as the strings distance.

I could light up the string to be played, or even cooler …
When using FFT code (Fast Fourier Transform), I could light up the string being played!
I’m probably going to try to implement this at a later time.

Wifi monitoring with Mikrotik Mqtt Nodered and Pushover

I’ve made a arpscanner in the past
https://www.henriaanstoot.nl/2019/10/15/arpscanner/
But i’m going to migrate the server this is running on.

So I played with ssh commands using ssh connections with a ssh-key, also using Ansible is possible.

ssh user@mikrotik /interface wireless registration-table print

But I didn’t like the continuous logins with automated logins.

So below solution is what i’ve implemented for now.

I’ve installed the IOT extra package from Mikrotik, now I can send MQTT messages from my Wifi enabled Mikrotiks to my Mosquitto broker.
(Download extra package zip, extract iot-7.x-arm.npk, upload this to your mikrotik files folder, and reboot)
The script I’m running on my Mikrotik, sends the active wifi connections with the comments. ( When a comment is set in the Access List, then it’s a know connection )

[admin@RB40111] /iot/mqtt> export
# may/15/2023 21:45:12 by RouterOS 7.9
# software id = xxxx-xxxx
#
# model = RB4011iGS+5HacQ2HnD
# serial number = xxxxxxxxxxxxxxxxx
/iot mqtt brokers
add address=10.1.x.y client-id=rb4011 name=NR

I made the following script on my MT named mqtt

:local broker "NR"

# MQTT topic where the message should be published
:local topic "rb4011/mac"

:foreach i in=[/interface wireless registration-table print proplist=mac-address as-value] do={
:local message "$i"

/iot mqtt publish broker=$broker topic=$topic message=$message
}

A schedule is needed to run this script every 15 minutes

[admin@RB40111] /system/scheduler> export
# may/15/2023 21:48:14 by RouterOS 7.9
# software id = xxxx-xxx
#
# model = RB4011iGS+5HacQ2HnD
# serial number = xxxxxxxxxxx
/system scheduler
add interval=15m name=mqtt on-event=mqtt policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=may/15/2023 start-time=13:30:54

Now all wifi connections will be send to topic rb4011/mac.

# Example
.id=*6a;comment=Mobile Henri wlan2;mac-address=44:46:87:xx:xx:xx

Using NodeRed I can make filters and notifications

Below function: get Mac and Comment from payload, if the comment is empty then it is a unknown connection … so send me a warning using Pushover.

// filter function
var output = msg.payload.split(";");

var comment = (output[1].split("="));
var mac = (output[2].split("="));

msg.payload={};
msg.payload = mac[1];
if (comment[1] == "") {
return msg;
}

// is xx:xx:xx:xx:xx:xx online? example
var output = msg.payload.split(";");

var comment = (output[1].split("="));
var mac = (output[2].split("="));

msg.payload={};
msg.payload = mac[1];
if (mac[1] == "xx:xx:xx:xx:xx:xx") {
return msg;
}



Now i’m getting a notification when an unknown wifi connection is made on my Access Point.
( I going to implement the Access List from MT at a later point. No access when not in the Access List)

HLK-LD2410B Mqtt socket and canvas

Follow up on yesterday’s post

Using a html page with javascript, I made a proof of concept displaying realtime information from the sensor.

The sensor is active using a Home Assistant integration.
https://www.henriaanstoot.nl/2022/11/07/home-assistant-nodered-update/

But using the Node-red integration, i take the payload and write this to a mqtt topic

The HTML page below reads the topic using the websocket configured in mosquitto and draws the distance using canvas

cat /etc/mosquitto/conf.d/websockets.conf
listener 9001
protocol websockets
allow_anonymous true


Distance drawn using canvas. Little dividers on top are meters

HTML PAGE with javascript

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
	<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
 	<script type = "text/javascript" 
         src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script type = "text/javascript">
	var connected_flag=0	
	var mqtt;
    var reconnectTimeout = 2000;
	var host="MQTTSERVER";
	var port=9001;
var sub_topic="web/#";
	function onConnectionLost(){
	console.log("connection lost");
	document.getElementById("status").innerHTML = "Connection Lost";
	document.getElementById("messages").innerHTML ="Connection Lost";
	connected_flag=0;
	}
	function onFailure(message) {
		console.log("Failed");
		document.getElementById("messages").innerHTML = "Connection Failed- Retrying";
        setTimeout(MQTTconnect, reconnectTimeout);
        }
	function onMessageArrived(r_message){
		out_msg="Message received "+r_message.payloadString+"<br>";
		//out_msg=out_msg+"Message received Topic "+r_message.destinationName;
		//console.log("Message received ",r_message.payloadString);
		console.log(out_msg);
		document.getElementById("messages").innerHTML =out_msg;
		var topic=r_message.destinationName;
		if(topic=="web/module1")
		{
		document.getElementById("module1").innerHTML =r_message.payloadString;
		}
		if(topic=="web/module2")
		{
		document.getElementById("module2").innerHTML =r_message.payloadString;
		
		var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var centerX = 10;
context.clearRect(0, 0, 1800, 1000);
var centerY = 10;
var radius = r_message.payloadString;

let circle = new Path2D();  // 
circle.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);

//context.fillStyle = 'white';

context.fillStyle = "rgba(255, 255, 255, 0.2)";
context.fill(circle); //   

context.lineWidth = 5;
context.strokeStyle = '#000066';
context.stroke(circle);  //

// top line
context.beginPath();
context.moveTo(10, 10);
context.lineTo(1500, 10);
context.stroke();

// 3x dividers		
context.beginPath();
context.moveTo(400, 0);
context.lineTo(400, 20);
context.stroke();
		
context.beginPath();
context.moveTo(800, 0);
context.lineTo(800, 20);
context.stroke();
		
context.beginPath();
context.moveTo(1200, 0);
context.lineTo(1200, 20);
context.stroke();
		
		}
		}
	function onConnected(recon,url){
	console.log(" in onConnected " +reconn);
	}
	function onConnect() {
	  // Once a connection has been made, make a subscription and send a message.
	document.getElementById("messages").innerHTML ="Connected to "+host +"on port "+port;
	connected_flag=1
	document.getElementById("status").innerHTML = "Connected";
	console.log("on Connect "+connected_flag);
	mqtt.subscribe(sub_topic);
	  }

    function MQTTconnect() {

	console.log("connecting to "+ host +" "+ port);
	var x=Math.floor(Math.random() * 10000); 
	var cname="controlform-"+x;
	mqtt = new Paho.MQTT.Client(host,port,cname);
	//document.write("connecting to "+ host);
	var options = {
        timeout: 3,
		onSuccess: onConnect,
		onFailure: onFailure,
      
     };
	
        mqtt.onConnectionLost = onConnectionLost;
        mqtt.onMessageArrived = onMessageArrived;
		//mqtt.onConnected = onConnected;

	mqtt.connect(options);
	return false;
  
 
	}
	function sub_topics(){
		document.getElementById("messages").innerHTML ="";
		if (connected_flag==0){
		out_msg="<b>Not Connected so can't subscribe</b>"
		console.log(out_msg);
		document.getElementById("messages").innerHTML = out_msg;
		return false;
		}
	var stopic= document.forms["subs"]["Stopic"].value;
	console.log("Subscribing to topic ="+stopic);
	mqtt.subscribe(stopic);
	return false;
	}
	function send_message(msg,topic){
		if (connected_flag==0){
		out_msg="<b>Not Connected so can't send</b>"
		console.log(out_msg);
		document.getElementById("messages").innerHTML = out_msg;
		return false;
		}
		var value=msg.value;
		console.log("value= "+value);
		console.log("topic= "+topic);
		message = new Paho.MQTT.Message(value);
		message.destinationName = "web/"+topic;

		mqtt.send(message);
		return false;
	}

	
    </script>

  </head>
  <body onload="MQTTconnect()">
	

 <table>
<tr><td>Sensor1:<td><td  id="module1"><td><td >
<tr><td>Sensor2:</td><td  id="module2"><td></tr>

</table>
<div id="status">Connection Status: Not Connected</div>
</div>
<br>

Messages:<p id="messages"></p>
     <canvas id="canvas" width="1600" height="1000"></canvas>  
  </body>
</html>

Got some new sensors (HLK-LD2410B)

Sometimes you forget you ordered something from Ali Express, it takes too long to arrive.

Today i’ve got this in my mailbox

These are HLK-LD2401B motion/presence detectors € 2,91 a piece.

While PIR sensors are slow and doing only motion sensing, these nice small and cheap devices are fast and have more outputs.

  • Bluetooth (can be used using home assistant integration)
  • Motion and presence
  • 60 degrees detection angle
  • Measurements to moving/static objects (while the datasheet mentions till 5 meter, i’ve got measurements well above that.
  • Fast updates, and i mean really fast
  • Only 7mm x 35mm
  • mmWave – 24GHz
  • GPIO Uart

According to the bad translation it can also measure if you ‘devour’ something. Dutch ‘vreten’ means wild fast eating something.
Setting the language to English gives me the word ‘fretting’

Right screenshot shows Coline sitting at a distance of 5.5 meters

Above, the update speed in HA

To try: connect Uart to remote ESP
and tweaking the device
https://www.youtube.com/watch?v=dAzHXpP3FcI
and distance gates

Maybe i can use some Triangulation go find the precise location of a person.

Little Led Matrix Maze game

While doing stuff like, making our home a little greener. Smoking meat. Working on diorama’s and my Escape game. I found time to make this little maze game.

Using an ESP32, mini joystick and a 8×8 led matrix. The objective is to get to the other side of the invisible maze.

It is a blind maze, so you have to figure out the path by trail and error. I found it quite fun and entertaining. (Coline had a hard time finishing the mode 3 maze)

I’ve got 3 settings on the maze:
0 – There is a trail where you have been.
1 – No trail, but only red leds showing walls.
2 – No trail, red reds and a reset to square 0,0 .. so you have to remember the path you previously took.

I’ll add code and schematics tomorrow …

Light blue shows you where you have been

Mode 2 game, reset when hitting a wall

Hitting the end block!

Maze is static at the moment, i’m planning to implement a “Recursive division method” to generate the maze.

Code

#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

// joystick pins
int up=33;
int down=25;
int left=32;
int right=26;
int cursor=32;

// 0 easy = trail // 1 only red walls // 2 = reset to 0.0
int mode=2;

//int trail=32;
int trail=0;

// Which pin on the Arduino is connected to the NeoPixels?
#define LED_PIN    2

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 64

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

// bits set opening in square
//    2
//   -----
// 1 |   | 4
//   -----
//     0
// so 5 is a passage from left to right (1+4) 

int maze[8][8] = {
  4,5,3,6,5,5,5,3,
  6,5,11,12,5,3,6,9,
  14,1,12,5,3,10,12,1,
  12,5,5,3,10,12,5,3,
  2,6,5,9,14,5,1,10,
  10,10,6,5,9,6,5,9,
  12,11,10,6,1,10,6,1,
  4,9,12,13,5,13,13,1,
  };

int displaymatrix[8][8] = { 
{ 0,1,2,3,4,5,6,7 },
{ 15,14,13,12,11,10,9,8 }, 
{16,17,18,19,20,21,22,23},
{31,30,29,28,27,26,25,24},
{32,33,34,35,36,37,38,39},
{47,46,45,44,43,42,41,40},
{48,49,50,51,52,53,54,55},
{63,62,61,60,59,58,57,56}
};

int x = 0;
int y = 0;

void setup() {
// joy
  pinMode(32, INPUT_PULLUP);
  pinMode(33, INPUT_PULLUP);
  pinMode(25, INPUT_PULLUP);
  pinMode(26, INPUT_PULLUP);

// mode set with jumpers
  pinMode(34, INPUT_PULLUP);
  pinMode(35, INPUT_PULLUP);

  Serial.begin(115200);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(10);
// set begin and end pixel
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.setPixelColor(displaymatrix[7][7], 0, 255, 0);

  strip.show();
//mode select  
 if (digitalRead(34) == 0) {
 mode=0;
 if (digitalRead(35) == 0) {
 mode=2;
 } else { 
 mode=1; 
 }
// finish effect
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

// reset to start (mode 2)
void reset2start() {
      strip.setPixelColor(displaymatrix[x][y], 0, 0, 0);
    strip.show();
  x = 0;
  y = 0;
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(10);
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.setPixelColor(displaymatrix[7][7], 0, 255, 0);
  strip.show();

}
// finish effect
void rainbow(uint8_t wait) {
  uint16_t i, j;
  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

void loop() {
    int isUp = (bitRead(maze[x][y], 1));
    int isRight = (bitRead(maze[x][y], 2));
    int isDown = (bitRead(maze[x][y], 3));
    int isLeft = (bitRead(maze[x][y], 0));
if (digitalRead(up) == 0) {
  if (isUp == 1){
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  x++;
  if ( x > 7) { x=7;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();

    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (digitalRead(down) == 0) {
  if (isDown == 1){
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  x--;
  if ( x < 0) { x=0;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();

    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (digitalRead(left) == 0) {
  if (isLeft == 1){
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  y--;
  if ( y < 0) { y=0;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();
    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (digitalRead(right) == 0) {
  if (isRight == 1){
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  y++;
  if ( y > 7) { y=7;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();

    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (x ==7 && y == 7){
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  rainbow(20);
}
delay(200);

}

Guess the code in Node Red

I asked ChatGPT to write code for me, i was not completely correct, and in Python. https://www.henriaanstoot.nl/2023/03/28/i-asked-chatgpt-to-write-code-for-a-crack-the-code-game/
I wrote my on version in JavaScript so it can be used in NodeRed as a function.

The codes are entered using a keypad (Arduino) and send via MQTT

Node Red Dash board

Code

var code = global.get("mysetcode");
var good = 0;
var wrong = 0;
var wrongplace = 0;
var match = false;
var wrongchars = 0;
var wrongplaced = 0;
var goodchars = 0;
var payloadcode = msg.payload.toString();

var usr_input = Array.from(payloadcode);
var secret_code = Array.from(code);
var secret_code1 = secret_code;

if (msg.payload === code) {
    match = true;
}
var result = "";

for (var i = 0; i < 4; i++) {
    var found = false;
    if (usr_input[i] === secret_code[i]) {
    usr_input[i] = "a";
    secret_code[i] = "b";
        good = good + 1;
        
    }
}

for (var i = 0; i < 4; i++) {
    var found = false;
    for (var j = 0; j < 4; j++) {
        if (usr_input[i] === secret_code[j]) {
                found = true;
        } 
    }
        if (!found) {
    wrong = wrong + 1;
    }
}

wrongchars = wrong - good;
wrongplaced = 4 - good - wrongchars;

msg.goodchars = good;
msg.wrongchars = wrongchars;
msg.wrongplace = wrongplaced;
msg.result = result;
msg.match = match;
return msg;

Converting a analog joystick to digital

When you need a large digital joystick, but only got an analog one. You can use below code to make the joystick act as a digital one.

I’ve played with analog joysticks on digital pins also, it can be done. But it can be buggy, and needs extra code.

Note: The joystick pins are marked with 5V, but when you use a Arduino which can only read till 3.3V using its ADC (Analog Digital Convertors), you can get some weird readings.
When moving down and left is reads okay, but up and right react as being connected together!
Just try it with 3.3V or use a resistor.

Above shows a ESP32, but below code has Arduino Nano pin names, change accordingly.

CODE

The code gives you a direction only once, you will need to move the stick to the middle position first and then move again.

Below gave me readings between 0 and 1024 (10 bits)
Hence the between 350 and 650 for the middle position.

Most will give you a reading between 0 and 4096.

Want to set the resolution yourself?

  analogReadResolution(10); // 10 bits
int val1 =0;
int val2 =0;

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    int sensorValue1 = analogRead(A0);
    int sensorValue2 = analogRead(A1);

    if (sensorValue1 > 650){
      if (val1 == 0){ 
      Serial.print("DOWN");
      Serial.println(" ");
      val1=1;
      }
    }
    else if (sensorValue1 < 350){ 
      if (val1 == 0){
       Serial.print("UP");
      Serial.println(" ");
      val1=1;
      }
    }
    else if (sensorValue2 > 350 && sensorValue2 < 650){
      val1=0;
    }
    
    
    if (sensorValue2 > 650){
      if (val2 == 0){ 
      Serial.print("LEFT");
      Serial.println(" ");
      val2=1;
      }
    }
    else if (sensorValue2 < 350){ 
      if (val2 == 0){
       Serial.print("RIGHT");
      Serial.println(" ");
      val2=1;
      }
    }
    else if (sensorValue2 > 350 && sensorValue2 < 650){
      val2=0;
    }

    delay(100);
}

Easy to setup switches puzzle with one pin

I’ve posted a switches puzzle here.
https://www.henriaanstoot.nl/2023/03/25/last-weeks-useful-schematics/

I was thinking of a easier setup which is “static”.
Mine has a 65535 possibility setup, but you can make an easy puzzle with below setup.

Set D3 to
pinMode(D3, INPUT_PULLUP);

Notice that I’ve placed the wires for some switches at the bottom, so these switches need to be set in the other direction “off” than the others.
Only 7 switches matter, you could use all of them.
When using a switch with only two connections, place the switch upside-down. Now OFF is switch with ON.

ON???
?OFFONOFF
??OFF?
?OFF??

is the correct setting

Some Arduino hints/tips/workarounds

These are last weeks findings, I will add to this page when I discover other useful things.

Platformio

  • always include “Arduino.h”
  • Order of functions matter! (Not with Arduino IDE)
  • setup serial monitor speed in platformio.ini
    monitor_speed = 115200

Arduino IDE

  • Build error “panic: runtime error: index out of range [3] with length 3” or length 4.
    Code probably correct, build with another board and build+upload with correct board as workaround.

Generic

  • Using a SSD1306 with other pins?
    For example with Adafruit_SSD1306.h
    in setup(){ place
    Wire.begin(5,4);

Python Baudot code for Wemos Matrix Led

I wrote a python script to generate binary data to include in my Arduino sketch.
This Arduino displays codes send though MQTT.

https://en.wikipedia.org/wiki/Baudot_code

CODE:

python3 matrix.py apple gives me

byte apple_Char[8] = {
  0b00000000,
  0b01000100,
  0b01111000,
  0b00000000,
  0b00110000,
  0b00000000,
  0b00111000,
  0b00000000
};

Python Code
import sys

a = [ 
        [0,0,0,0,0,0,0,0 ], 
        [0,0,0,0,0,0,0,0 ], 
        [0,0,0,0,0,0,0,0 ], 
        [0,0,0,0,0,0,0,0 ], 
        [0,0,0,0,0,0,0,0 ], 
        [0,0,0,0,0,0,0,0 ], 
        [0,0,0,0,0,0,0,0 ], 
        [0,0,0,0,0,0,0,0 ] 
    ] 

letters = [
        [0,1,1,0,0,0,0,0 ],
        [0,1,0,0,0,1,1,0 ],
        [0,0,1,0,1,1,0,0 ],
        [0,1,0,0,0,1,0,0 ],
        [0,1,0,0,0,0,0,0 ],
        [0,1,0,0,1,1,0,0 ],
        [0,0,1,0,0,1,1,0 ],
        [0,0,0,0,1,0,1,0 ],
        [0,0,1,0,1,0,0,0 ],
        [0,1,1,0,0,1,0,0 ],
        [0,1,1,0,1,1,0,0 ],
        [0,0,1,0,0,0,1,0 ],
        [0,0,0,0,1,1,1,0 ],
        [0,0,0,0,1,1,0,0 ],
        [0,0,0,0,0,1,1,0 ],
        [0,0,1,0,1,0,1,0 ],
        [0,1,1,0,1,0,1,0 ],
        [0,0,1,0,0,1,0,0 ],
        [0,1,0,0,1,0,0,0 ],
        [0,0,0,0,0,0,1,0 ],
        [0,1,1,0,1,0,0,0 ],
        [0,0,1,0,1,1,1,0 ],
        [0,1,1,0,0,0,1,0 ],
        [0,1,0,0,1,1,1,0 ],
        [0,1,0,0,1,0,1,0 ],
        [0,1,0,0,0,0,1,0 ]
        ]

number=0
word=str(sys.argv[1])

for col in range(len(word)) :
    character=word[col]

    number = ord(character) - 97
    nextcol = col + 1
    for row in range(len(a[col])) :
        a[row][nextcol] = letters[number][row]


print("byte " + word + "_Char[8] = {")
for i in range(len(a)) : 
    print("  0b", end = '')
    for j in range(len(a[i])) : 
        print(a[i][j], end="")   
    if i < 7:
        print(",")
print()
print("};")

Arduino test code

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClient.h>


#include "WEMOS_Matrix_LED.h"
MLED mled(5); //set intensity=5

const char* wifi_ssid = "MYSSID"; // Enter your WiFi name
const char* wifi_password =  "MYSSIDPASS"; // Enter WiFi password
const char* mqtt_server = "MYMQTTSERVER";
const int mqtt_port = 1883;
const char* mqttUser = "";
const char* mqttPassword = "";
#define MSG_BUFFER_SIZE  (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

WiFiClient espClient;

PubSubClient mqtt(espClient);

void setup_wifi() {
  delay(10);
  WiFi.mode(WIFI_STA);
  WiFi.begin(wifi_ssid, wifi_password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}
 
byte clear_Char[8] = {  
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};
 
byte baudot_Char[8] = {
  0b11111111,
  0b01101010,
  0b00011100,
  0b11111111,
  0b00110100,
  0b00010000,
  0b00000100,
  0b11111111  
};
 

 
#define TIME 500
 
void setup() { 
    Serial.begin(115200);
      setup_wifi();
        mqtt.setServer(mqtt_server, mqtt_port);

WiFiClient espClient;
PubSubClient mqtt(espClient);

  mqtt.setClient(espClient);
  mqtt.setServer(mqtt_server, mqtt_port);
      delay(500);

  mqtt.subscribe("escape/matrixledin");
        delay(500);

  mqtt.setCallback(callback);

  }

void callback(char* topic, byte* payload, unsigned int length) {
        Serial.println("callback");
    String topicStr = topic;
      byte value = atoi((char*)payload);
        snprintf (msg, MSG_BUFFER_SIZE, "%1d", value);

              mqtt.publish("escape/matrixledout", msg);
       if (value == 1){

drawChar(baudot_Char); 

 }else if (value == 0){
  drawChar(cleat_Char); 
  }else if (value == 2){
  drawChar(test_Char); 
  }else if (value == 3){
  drawChar(no_Char); 
 }
 }

void reconnect() {

  while (!mqtt.connected()) {
    String clientId = "matrixClient-";
    clientId += String(random(0xffff), HEX);
    if (mqtt.connect(clientId.c_str())) {
      mqtt.publish("escape/outTopic", "hello from 8x8led module");
                Serial.println("resubscribe");

      mqtt.subscribe("escape/matrixledin");
        mqtt.setCallback(callback);

    } else {
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
 
void loop() {

 if (!mqtt.connected()) {
          Serial.println("reconnect called");
    reconnect();
  }
    mqtt.loop();

}
 
void drawChar(byte character[8]) {
  for(int y=7;y>=0;y--) {
  for (int x=0; x <= 7; x++) { 
    if (character[(7-y)] & (B10000000 >> x)) {
     mled.dot(x,y); // draw dot
    } else {
     mled.dot(x,y,0);//clear dot
    }
  }
  mled.display();  
  }
}