Skip to content

Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector

Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector

Components

Hardware components

x 1


x 1


Project description

Welcome to my blog! This is my other self-project to use RoboDK as a main station ? operate the robot and indicate the current status by LED Towner, we will use opencv to implement a color detector in python to detect Red/Yellow/Green Colors ,and publish these statuses via MQTT. Beckhoff TwinCAT TF6701 is used to subscribe to the topic also and implement a Data logger,Finally, A M5Core2+W5500 Lan Module will also subscribe to the topics from MQTT Broker that are built from Raspberry-pi3. There are some goals in this project and I will explain them step by step;
  • Create a RoboDK station with LED Tower display
  • Play with the RoboDK 2D Camera simulation interface
  • understand the opencv-python
    • how to read the images from filesystem
    • how to read the images from RoboDK
    • What is the RGB/HSV Color Model?
    • how to make a color detector?
    • how to draw the Contours?
  • implement the python MQTT Client
  • understand and program the Beckhoff TwinCAT Function TF6701
  • Get the local-time and shifting the data 1 by 1 in the logging function
  • setup the MQTT Broker in Raspberry-pi3
  • setup the M5Stack Lan Module
  • Implementing the MQTT Client with M5Stack in C Language
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector

Other Project

Here is my other project;) Please feel free to access it.

Color Detecor

Opencv installation

Please use this command to install Opencv in your machine.
pip?install?opencv-python

if Trouble

Concept

Now I will explain some basic concepts in opencv and skills that are used in this tutorial.

Import images/Show

Here is a sample code to import an image into opencv and show it.
import?cv2 import?numpy?as?np # Reading the image img = cv2.imread(‘image.jpg’) # Showing the output cv2.imshow(“Image”, img) cv2.waitKey(0) cv2.destroyAllWindows()
You would see the image like this.
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, Import images/Show

RGB color model

RGB color values are supported in all browsers. An RGB color value is specified with: rgb(red, green, blue). Each parameter (red, green, and blue) defines the intensity of the color as an integer between 0 and 255. For example, rgb(0, 0, 255) is rendered as blue, because the blue parameter is set to its highest value (255) and the others are set to 0.
RGB color model
please reference w3c school to get more information https://www.w3schools.com/colors/colors_rgb.asp?color=rgb(253,%20205,%20161)
Becareful!
In Opencv, the sequence is not RGB and BGR.
RGB Calculator
You can find thousands of RGB simulators on the internet and please practice by yourself;) https://www.w3schools.com/colors/colors_rgb.asp
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, RGB Calculator

HSV Model

The HSV color model shares most of its properties with HSL. (It is recommended that you read about HSL first as this page will build on the page about HSL). The range is 0-360 ,0-100%,0-100%. Hues are the three primary colors (red, blue, and yellow) and the three secondary colors (orange, green, and violet) that appear in the color wheel or color circle. When you refer to hue, you are referring to pure color, or the visible spectrum of basic colors that can be seen in a rainbow. Color saturation is the purity and intensity of a color as displayed in an image. The higher the saturation of a color, the more vivid and intense it is. The lower a color’s saturation, or chroma, the closer it is to pure gray on the grayscale. Learn more about saturation in our guide here. Color value refers to the relative lightness or darkness of a color. We perceive color value based on the quantity of light reflected off of a surface and absorbed by the human eye. We refer to the intensity of the light that reaches the eye as “luminance.” Please reference this link to get more information: http://color.lukas-stratmann.com/color-systems/hsv.html
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, HSV Model
Becareful!
For HSV in opencv, hue range is [0,179], saturation range is [0,255], and value range is [0,255]. And different software uses different scales.
HSV Calculator
You can find thousands of HSV simulators on the internet and please practice by yourself;) http://color.lukas-stratmann.com/color-systems/hsv.html
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, HSV Calculator
Mask
We will use HSV instead of RGB Model to detect the color in the image. Here is a table to show the range of Red,Green and Blue.
Rnage Range in Opencv
Red 0-60,300-360 0-30,150-179
Green 60-189 30-90
Blue 180-300 90-150
Sample
Here is an example to show you how to detect the yellow color in a banana image. we will set the lower_bound and upper_bound of the yellow color as a numpy and create a mask to filter it.
import cv2 import numpy as np # Reading the image img = cv2.imread(‘image.jpg’) # convert to hsv colorspace hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # lower bound and upper bound for Green color lower_bound = np.array([20, 50, 50]) upper_bound = np.array([100, 255, 255]) # find the colors within the boundaries mask = cv2.inRange(hsv, lower_bound, upper_bound) # Segment only the detected region segmented_img = cv2.bitwise_and(img, img, mask=mask) cv2.imshow(“Image”, segmented_img) cv2.waitKey(0) cv2.destroyAllWindows()
Good, here is the banana!
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, Sample
Contours
Contours are the concepts that I explained in the last tutorial with Beckhoff Tc3_Vision. Please reference this tutorial to get more information:
Sample
In the previous sample, we detected the yellow color in a banana image. Now we will draw the Contours inside the image.
import cv2 import numpy as np # Reading the image img = cv2.imread(‘image.jpg’) # convert to hsv colorspace hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # lower bound and upper bound for Green color lower_bound = np.array([20, 50, 50]) upper_bound = np.array([100, 255, 255]) # find the colors within the boundaries mask = cv2.inRange(hsv, lower_bound, upper_bound) # Segment only the detected region segmented_img = cv2.bitwise_and(img, img, mask=mask) # Find contours from the mask contours, hierarchy = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) output = cv2.drawContours(segmented_img, contours,-1,(0,255,0),3) # Showing the output cv2.imshow(“Output”, output) cv2.waitKey(0) cv2.destroyAllWindows()
Contours is drawn.
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, Sample

WorkFlow

Finally, you can follow this flow to do the color detector.
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, WorkFlow

RoboDK Side

Here is the RoboDK station, Camera,3 colors of Signal Tower and A Robot. In this tutorial I will just start the Robot program manually(click the robot program). If you want, please follow my reference link to program your station to start it from PLC/Other Devices.
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, RoboDK Side

Reference Link

Light Tower Signal

Here is the tutorial that shows you how to create the Light ON/OFF control. The Idea is very easy ? Place a Light with deep color and place another one with light color. Finally, using Event to Show/Hide the objects.
Light Tower Signal

Red

Here is the Red Color.
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, Red

Yellow

Here is the Yellow Color.
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, Yellow

Green

Here is the Green Color.
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, Green

Signal Flow

The Color tower will be turned on with different colors, depending on the status of the Robot. If the Robot Program is started>Green will be on,Yellow and Red will be off. If the Robot Program is started and the status is waiting for IO_5>Yellow will also be on. If the Robot Program is started and the status is passed for the IO_5 waiting Step, Yellow will be off. If the Robot Program ends>Green will be off and red will be on.
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, Signal Flow

WorkFlow

The working Flow of the Color Detector is integrated into the program from the previous opencv program,and also adds the features of publishing the topic to an MQTT Broker. The topic would be the current status of Lamp Tower. ?
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, WorkFlow

Code

Here is the Code in RoboDK to implement a Color detector and MQTT Client.
from?robodk?import?robolink? ? # RoboDK API from?robodk?import?robomath? ? # Robot toolbox import?cv2 import?numpy?as?np import?paho.mqtt.client?as?mqtt #MQTT Client def?on_connect(client,userdata,flag,rc): print(‘Connected with result code ‘+str(rc)) client.subscribe(‘RoboDK/Station/s1/Lamp/Red’) def?on_disconnect(client,userdata,flag,rc): if?rc !=0: print(‘Something Wrong..’) def?on_publish(client,userdata,mid): print(‘publish: {0}’.format(mid)) RDK = robolink.Robolink() count=0 CAM_NAME=’Camera1′ # GREEN_LOWER_BOUND=np.array([40, 150, 150]) GREEN_HIGHER_BOUND=np.array([100, 255, 255]) RED_LOWER_BOUND=np.array([130, 150, 150]) REG_HIGHER_BOUND=np.array([179, 255, 255]) YELLOW_LOWER_BOUND=np.array([20, 150, 150]) YELLOW_HIGHER_BOUND=np.array([35, 255, 255]) cam_item = RDK.Item(CAM_NAME) if?not?cam_item.Valid(): raise?Exception(“Camera not found! %s” % CAM_NAME) cam_item.setParam(‘Open’, 1)? # Force the camera view to open BROCKER_URL=’192.168.1.50′ BROCKET_PORT=1883 MQTT_BASIC_TOPIC=’RoboDK/Station/s1/’ #???????????- # Settings PROCESS_COUNT = 300? # How many frames to process before exiting. -1 means indefinitely. client=mqtt.Client() client.on_connect=on_connect client.on_disconnect=on_disconnect client.on_publish=on_publish client.connect(BROCKER_URL,BROCKET_PORT,60) while?count < PROCESS_COUNT?or?PROCESS_COUNT < 0: Green,Red,Yellow=False,False,False print(“=============================================”) print(“Processing image %i” % count) count += 1 #???????????????- # Get the image from RoboDK bytes_img = RDK.Cam2D_Snapshot(“”, cam_item) if?bytes_img == b”: raise # Image from RoboDK are BGR, uchar, (h,w,3) nparr = np.frombuffer(bytes_img, np.uint8) img = cv2.imdecode(nparr, cv2.IMREAD_UNCHANGED) hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) mask_y = cv2.inRange(hsv, YELLOW_LOWER_BOUND, YELLOW_HIGHER_BOUND) mask_r = cv2.inRange(hsv, RED_LOWER_BOUND, REG_HIGHER_BOUND) mask_g = cv2.inRange(hsv, GREEN_LOWER_BOUND, GREEN_HIGHER_BOUND) # Find contours from the mask contours_y, hierarchy = cv2.findContours(mask_y.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours_r, hierarchy = cv2.findContours(mask_r.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours_g, hierarchy = cv2.findContours(mask_g.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) output = cv2.drawContours(img, contours_y,-1,(255,197,250),3) output = cv2.drawContours(img, contours_r,-1,(255,197,250),3) output = cv2.drawContours(img, contours_g,-1,(255,197,250),3) output = cv2.resize(output, (int(output.shape[1] * .3), int(output.shape[0] * .3))) if?img?is?None?or?img.shape == (): raise key = cv2.waitKey(200) if?key == 27: break? # User pressed ESC, exit cv2.imshow(“Output”, output) client.publish(MQTT_BASIC_TOPIC+’Lamp/Yellow’,str(len(contours_y))) client.publish(MQTT_BASIC_TOPIC+’Lamp/Red’,str(len(contours_r))) client.publish(MQTT_BASIC_TOPIC+’Lamp/Green’,str(len(contours_g))) if?len(contours_y) >0: Yellow=True if?len(contours_r) >0: Red=True if?len(contours_g) >0: Green=True cv2.waitKey(500) cv2.destroyAllWindows()

Install Broker

Some Useful Link while using Raspberry
Here is the tutorial to build a broker in the raspberry pi/ubuntu.
If the connection is refused:

TwinCAT Side

Reference Link

Please reference these links to operate with MQTT in TwinCAT.

WorkFlow

In the TwinCATSide, the work flow is very simple. Get the Local time cyclically>set the MQTT Connection Parameters>Subscribe the Topic> if any new messages come from these topics> define the topic title>set the logger trigger flag>logged the status>loop back.
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, WorkFlow

Program

DUT_Log

This is the DUT of data logging, A String format of timestamp and the status is defined here.
TYPE?DUT_Log : STRUCT timeStamp:STRING; Status?:DINT; END_STRUCT END_TYPE

GVL_Logger

The Global variables of the logging data. You can adjust the array length as you like.
VAR_GLOBAL Red,Green,Yellow:ARRAY[0..99]OF DUT_Log; END_VAR

Function Block FB_GetLocalTime

Here is the Function Block to get the Local time of the runtime. Please reference this tutorial? to get more information:
VAR_INPUT
True=Get the Local Time
VAR_INPUT i_bEnable:BOOL:=TRUE; END_VAR
VAR
Some variables for internal use and the instance of FB_LocaSystemTime.
VAR bTimeSyncError?:BOOL; TimeStruct :TIMESTRUCT; InitTimeStruct :TIMESTRUCT; LocalSystemTime :FB_LocalSystemTime; dwCycle:INT:=1; TON:TON; END_VAR
PROGRAM
Here is the main program, it is a very simple cyclic called the FB_LocalSystemTime() and detects any error of this function block.
LocalSystemTime( bEnable:=i_bEnable ,dwCycle:=1 ); TON( IN:=NOT LocalSystemTime.bValid ,PT:=INT_TO_TIME( (dwCycle+ciTimeValidCheckOffset)*1000 ) ); TimeStruct:=LocalSystemTime.systemTime; IF TON.Q THEN bTimeSyncError:=TRUE; END_IF
METHOD Init : BOOL
A method to reset the current time value to default.
TimeStruct:=InitTimeStruct;
METHOD Reset : BOOL
A method to reset the error flag of function block.
bTimeSyncError:=FALSE;
METHOD TimeInString : String
This is a method to change the time value to a String format and use the CONCAT function to join them. Here is the format:yy-mm-dd-hh:mm:ss
VAR _string:STRING; END_VAR _string:=CONCAT(WORD_TO_STRING(TimeStruct.wYear),’-‘); _string:=CONCAT(_string,WORD_TO_STRING(Timestruct.wMonth)); _string:=CONCAT(_string,’-‘); _string:=CONCAT(_string,WORD_TO_STRING(Timestruct.wDay)); _string:=CONCAT(_string,’-‘); _string:=CONCAT(_string,WORD_TO_STRING(TimeStruct.wHour)); _string:=CONCAT(_string,’:’); _string:=CONCAT(_string,WORD_TO_STRING(TimeStruct.wMinute)); _string:=CONCAT(_string,’:’); _string:=CONCAT(_string,WORD_TO_STRING(TimeStruct.wSecond)); TimeInString:=_string;
PROPERTY LocalTimeStruct : TIMESTRUCT
GET
The property to get the current system time.
LocalTimeStruct:=LocalSystemTime.systemTime;
PROPERTY LocalTimeValid : Bool
GET
The property to get the current system time is valid or not.
LocalTimeValid:=LocalSystemTime.bValid;
PROPERTY TimeSyncError : Bool
GET
The property to get the current function block is normal or not.
TimeSyncError:=bTimeSyncError;

FUNCTION_BLOCK FB_Logger

Here is a function block to save the LED Tower status and the time. 0=Off、1=On.
VAR_INPUT
VAR_INPUT i_TimeStamp:STRING; i_Value?? ? :DINT; END_VAR
VAR_IN_OUT
VAR_IN_OUT io_logData:ARRAY[*]OF?DUT_Log; END_VAR
VAR
VAR index:INT:=0; END_VAR
METHOD ClearLog : BOOL
A method to clear the log.
VAR_INPUT
VAR_INPUT bStart:BOOL; END_VAR
VAR_INST
VAR_INST R_TRIG:R_TRIG; END_VAR
VAR
VAR i:DINT; END_VAR
PRGORAM
R_TRIG(CLK:=bStart); IF?R_TRIG.Q?THEN FOR?i:=ArrayLower?TO?ArrayHigher?DO io_logData[i].Status:=0; io_logData[i].timeStamp:=’ ‘; END_FOR END_IF
METHOD datalog : BOOL
The method to save and “shift” the log.
VAR_INPUT
VAR_INPUT bStart:BOOL; END_VAR
VAR_INST
VAR_INST R_TRIG:R_TRIG; END_VAR
VAR
VAR i:DINT:=0; END_VAR
PROGRAM
Here is a small program to auto calculate the DUT size that needs to be shifted. MEMCPY is a function to copy the memory from source to destination. [0] is the newest value.
datalog:=FALSE; R_TRIG(CLK:=bStart); IF R_TRIG.Q THEN MEMCPY( destAddr:=ADR(io_logData[1]) ,srcAddr:=ADR(io_logData[0]) ,n:=SIZEOF(io_logData[0])*ArrayHigher ); io_logData[0].Status:=i_Value; io_logData[0].timeStamp:=i_TimeStamp; datalog:=TRUE; END_IF
PROPERTY ArrayHigher : DINT
The property gets the array lower and Upper.
GET
ArrayHigher:=UPPER_BOUND(io_logData,1);
PROPERTY ArrayLower : DINT
GET
ArrayLower:=LOWER_BOUND(io_logData,1);

MAIN

VAR
PROGRAM MAIN VAR MQTTClient:FB_IotMqttClient; payload:STRING(255); payload_r,payload_y,payload_g:STRING(20); fbMessageQueue : FB_IotMqttMessageQueue; fbMessage? ? ? : FB_IotMqttMessage; sTopic :STRING; bSetNullTermination?:BOOL; bScbscribed:BOOL; sTopicReceived:STRING(255); Value_r,Value_g,Value_y:DINT; GetLocalTime:FB_GetLocalTime; stTimeInString:STRING; datalog_r,datalog_g,datalog_y:FB_Logger; LastTimeStamp_r,LastTimeStamp_g,LastTimeStamp_y:STRING; i1,i2:DINT; bTest:BOOL; binit:BOOL; logTrigger_r,logTrigger_g,logTrigger_y:BOOL; hmi_LP_r,hmi_LP_g,hmi_LP_y:BOOL; END_VAR
PROGRAM
//Get Local Time GetLocalTime( i_bEnable:=TRUE ); IF GetLocalTime.LocalTimeValid THEN stTimeInString:=GetLocalTime.TimeInString(); END_IF; //init IF binit THEN LastTimeStamp_r:=stTimeInString; LastTimeStamp_g:=stTimeInString; LastTimeStamp_y:=stTimeInString; binit:=FALSE; END_IF //MQTT Client Setup //Parameters MQTTClient.sHostName:=’192.168.1.50′; MQTTClient.nKeepAlive:=60; MQTTClient.ipMessageQueue:=fbMessageQueue; //Execute() must always Run MQTTClient.Execute(bConnect:=TRUE); //Subscribe Topic sTopic:=’RoboDK/Station/s1/#’; IF MQTTClient.bConnected THEN IF NOT bScbscribed THEN MQTTClient.Subscribe( sTopic:=sTopic ,eQoS:=0 ); bScbscribed:=TRUE; END_IF END_IF //Check Message From Broker IF fbMessageQueue.nQueuedMessages > 0 THEN IF fbMessageQueue.Dequeue(fbMessage:=fbMessage) THEN //Get the Topic fbMessage.GetTopic(pTopic:=ADR(sTopicReceived), nTopicSize:=SIZEOF(sTopicReceived)); //Compare IF fbMessage.CompareTopic(sTopic:=’RoboDK/Station/s1/Lamp/Red’) THEN payload_r:=’ ‘; fbMessage.GetPayload(pPayload:=ADR(payload_r), nPayloadSize:=SIZEOF(payload_r), bSetNullTermination:=FALSE); LastTimeStamp_r:=GetLocalTime.TimeInString(); logTrigger_r:=TRUE; ELSIF fbMessage.CompareTopic(sTopic:=’RoboDK/Station/s1/Lamp/Yellow’) THEN payload_y:=’ ‘; fbMessage.GetPayload(pPayload:=ADR(payload_y), nPayloadSize:=SIZEOF(payload_y), bSetNullTermination:=FALSE); LastTimeStamp_y:=GetLocalTime.TimeInString(); logTrigger_y:=TRUE; ELSIF fbMessage.CompareTopic(sTopic:=’RoboDK/Station/s1/Lamp/Green’) THEN payload_g:=’ ‘; fbMessage.GetPayload(pPayload:=ADR(payload_g), nPayloadSize:=SIZEOF(payload_g), bSetNullTermination:=FALSE); LastTimeStamp_g:=GetLocalTime.TimeInString(); logTrigger_g:=TRUE; END_IF END_IF END_IF //Convert the Value from String to Numbers Value_r:=STRING_TO_DINT(payload_r); Value_g:=STRING_TO_DINT(payload_g); Value_y:=STRING_TO_DINT(payload_y); //Hmi hmi_LP_r:=Value_r =1; hmi_LP_g:=Value_g =1; hmi_LP_y:=Value_y =1; //Data logger //Green Lamp datalog_g( i_TimeStamp:=stTimeInString ,i_Value:=Value_g ,io_logData:=GVL_Logger.Green ); IF datalog_g.datalog(bStart:=logTrigger_g) THEN logTrigger_g:=FALSE; END_IF //Yellow Lamp datalog_y( i_TimeStamp:=stTimeInString ,i_Value:=Value_y ,io_logData:=GVL_Logger.Yellow ); IF datalog_y.datalog(bStart:=logTrigger_y) THEN logTrigger_y:=FALSE; END_IF //Red Lamp datalog_r( i_TimeStamp:=stTimeInString ,i_Value:=Value_r ,io_logData:=GVL_Logger.Red ); IF datalog_r.datalog(bStart:=logTrigger_r) THEN logTrigger_r:=FALSE; END_IF

Visulization

A screen to show the LED Tower status in Beckhoff TE1800.
Project#RoboDK x TwinCAT x MQTT x Opencv Color Dectector, Visulization

M5Core2 Side

Please reference this tutorial to setup a M5Stack with W5500 LAN Module.

Code

Here is the Code in M5Stack to implement an MQTT Client in C Language, Subscribe the Topic from RoboDK and Display the Current LED Tower status in the LED Display.
#include <M5Core2.h> #include <SPI.h> #include <Ethernet2.h> #include <PubSubClient.h> #define SCK 18 #define MISO 19 #define MOSI 23 #define CS 26 byte?mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x08, 0xE1 }; IPAddress Local(192, 168, 1, 211); EthernetClient ethClient; PubSubClient mqttClient(ethClient); //MQTT Broker const?char?*ENDPOINT=”192.168.001.050″; const?int?PORT=1883; char?*MYID=”M5Stack”; char?*PUBLISHTOPIC=”M5Stack/pub”; char?*SUBTOPIC=”RoboDK/Station/s1/#”; // int?GreenStatus=0; int?RedStatus=0; int?YellowStatus=0; // char?*SubtopicYellow=”RoboDK/Station/s1/Lamp/Yellow”; char?*SubtopicGreen=”RoboDK/Station/s1/Lamp/Green”; char?*SubtopicRed=”RoboDK/Station/s1/Lamp/Red”; void?callback(char* topic,?byte* payload,?unsigned?int?length) { Serial.print(“Message arrived [“); Serial.print(topic); int?result_yellow=strcmp(topic,SubtopicYellow); int?result_red=strcmp(topic,SubtopicRed); int?result_green=strcmp(topic,SubtopicGreen); if (result_yellow ==0 ){ Serial.print(payload[0]); if (payload[0]==48){ YellowStatus=0; Serial.print(YellowStatus); } if (payload[0]==49){ YellowStatus=1; Serial.print(YellowStatus); } } if (result_red ==0 ){ Serial.print(payload[0]); if (payload[0]==48){ RedStatus=0; } if (payload[0]==49){ RedStatus=1; } } if (result_green ==0 ){ Serial.print(payload[0]); if (payload[0]==48){ GreenStatus=0; } if (payload[0]==49){ GreenStatus=1; } } Serial.print(“] “); for (int?i = 0; i < length; i++) { Serial.print((char)payload[i]); } } void?setup(){ //If LAN Modules is used,Please use this operation mode M5.begin(true, true, true, false, kMBusModeInput); Serial2.begin(115200, SERIAL_8N1, 13, 14); // START M5.Lcd.fillScreen(BLACK); M5.Lcd.setCursor(10, 10); M5.Lcd.setTextColor(WHITE); M5.Lcd.setTextSize(3); M5.Lcd.printf(“Inited..n”); M5.Lcd.printf(“IP:192.168.1.211n”); M5.Lcd.printf(“Mac:90-A2-DA-x0F-08-E1n”); mqttClient.setServer(ENDPOINT, PORT); mqttClient.setCallback(callback); SPI.begin(18, 19, 23, -1); Ethernet.init(26); Ethernet.begin(mac, Local); connectMQTT(); } void?mqttLoop() { if (!mqttClient.connected()) { connectMQTT(); } mqttClient.loop(); } void?connectMQTT() { while (!mqttClient.connected()) { Serial.print(“Connection Loop..”); if (mqttClient.connect(MYID)) { Serial.println(“Connected.”); int?qos = 0; mqttClient.subscribe(SUBTOPIC, qos); Serial.println(“Subscribed.”); } else { Serial.print(“Failed. Error state=”); Serial.print(mqttClient.state()); // Wait 5 seconds before retrying delay(1000); } } } long?messageSentAt = 0; int?count = 0; char?pubMessage[128]; int?led,red,green,blue; int?status=0; void?loop() { mqttLoop(); long?now = millis(); if (now ? messageSentAt > 500) { M5.update(); M5.Lcd.fillScreen(BLACK); if (YellowStatus ==1){ M5.Lcd.fillCircle(160, 120, 30, YELLOW); } if (YellowStatus ==0){ M5.Lcd.drawCircle(160, 120, 30, YELLOW); } if (RedStatus ==1){ M5.Lcd.fillCircle(240, 120, 30, RED); } if (RedStatus ==0){ M5.Lcd.drawCircle(240, 120, 30, RED); } if (GreenStatus ==1){ M5.Lcd.fillCircle(80, 120, 30, GREEN); } if (GreenStatus ==0){ M5.Lcd.drawCircle(80, 120, 30, GREEN); } Serial.print(YellowStatus); messageSentAt = now; sprintf(pubMessage, “{”count”: %d}”, count++); Serial.print(“Publishing message to topic “); Serial.println(PUBLISHTOPIC); Serial.println(pubMessage); mqttClient.publish(PUBLISHTOPIC, pubMessage); Serial.println(“Published.”); } }

Result

Result-M5Core2 Side

Source Code

Please access this link to download the source code; You can find the RoboDK Project,TwinCAT Project and the M5Stack Source Code. https://github.com/soup01Threes/TwinCAT3/blob/main/Project_RoboDK_Color_Detector.zip

Documents

Comments

Comments