STONE LCD Screen ventilator Project

Remember “Meet the Woofers”? As shown in picture (1), in this long story, the author Roku Mu Xue writes about the lonely old man Li Keng Chen and his daughter Dabao and the dog Dumbao. Li Keng Chen first did not like the dog Dumbao, his daughter left home to work in the north, it is the dog Dumbao has been with him; but the dog always woke him up in the middle of the night, and later learned that the old man Li Keng Chen suffered from paroxysmal sleep apnea syndrome, the dog Dumbao woke up to save his life!

Meet the Woofers
Meet the Woofers

If you don’t have that smart a DOG, then you can get an Angel sleep ventilator, Figure (2). It can help you prevent apnea by opening your blocked airway during sleep with a continuous positive pressure —-CPAP mode with different weight pressure adjustment values see figure (3). You can also set a 15-60 minute delayed pressure boost (you can use sec instead of min for visualizing the effect during the demo) to bring the air pressure up gradually only after you fall asleep to avoid starting with high air pressure that will affect your sleep.

Figure (2) Main interface of sleep ventilator
Figure (2) Main interface of sleep ventilator
Figure (3) CPAP mode air pressure adjustment reference values
Figure (3) CPAP mode air pressure adjustment reference values

The display interface of this sleep ventilator uses a 5.6″ STONE serial touch screen with a backlight, rich colors, and a serial port for easy communication with the main control board, and the touch input also eliminates the keyboard, making the whole ventilator more simple and generous in appearance. Adjustable pressure value and delay time are sliding options – Figure (4), more convenient operation. In addition, the delay time countdown and the pressure gauge display value are shown in a special interface — Figure (5), which is intuitive and clear. The development process is recorded as follows.

Figure (4) Parameter adjustment interface
Figure (4) Parameter adjustment interface
Figure (5) Pressure and countdown ramp-up display screen
Figure (5) Pressure and countdown ramp-up display screen

Description

  • HMI and control creation instructions
  • Interface Download
  • Hardware connection and command testing
  • debugging code

1、Ventilator Screen Design And Control Creation Instructions

As in figure (2), enter the ventilator parameter adjustment interface through the enter button, slide up and down to adjust the air pressure value on the left, and also slide up and down to adjust the delayed boost time on the right. Click “Start” to start boosting, or delay boosting, with a red “STOP” button to leave or other needs to stop boosting at any time. Press the “Pressure gauge” button to enter the pressure display and time delay countdown display.

You can adjust the parameter: round_rsdius: 50 on the button property page to achieve round and arc-shaped buttons. Figure (6) shows a screenshot of the properties of the “STOP” button.

Figure (6) Parameter design of the circular button
Figure (6) Parameter design of the circular button

The font will appear lowercase in the STONE display and larger in the PC, so design the font size as large as possible in the PC so that it doesn’t feel too small when downloaded to the screen, resulting in multiple version adjustments for font size.

Text_selector selector design middle highlighted font than the two sides of the font is larger, the color red more conspicuous, such as ts11 property parameters see Figure (7). The actual effect is shown in Figure (4).

Figure (7) Air pressure selector parameter design
Figure (7) Air pressure selector parameter design
Figure (8) Pressure gauge pointer properties
Figure (8) Pressure gauge pointer properties

The icon style of the pointer gauge_pointer control is selected in the image in Figure (8), the anchor point of the pointer is set by anchor_x, anchor_y, range 0.0 – 1.0. angle setting, currently set in PC -140 is pointing to air pressure 0, in the screen, the original position is in the middle 0 degrees, need program command to re-specify.

Figure (2) and Figure (3) interface involving the name and range of controls and content needed for programming are displayed together in a unified manner for easy access during programming.

Programming Control Name

Figure (2) Parameter adjustment interface:

Start button name = b11
Stop button name = b12
Pressure gauge button name = b13
Delayed pressure boost selector button name = cb1
Pressure selector name = ts11 range 1-20
Delay time selector name = ts12 range 1-60

Figure (3) Pressure and countdown display screen:

Pressure gauge pointer name = gp1 Pressure value 0: -140, 20: -110
Min countdown name = l21
Sec countdown name = l22

2、Interface Download

By clicking debug — “download” under the main menu, select the respirator folder, and a subfolder with the same name as the project will be generated (the last generated folder should be renamed before each download. Otherwise, it will return an error);

check the dial switch on the back of the STONE serial screen to the “device” position above, and use the USB communication cable to directly connect the PC and the USB interface of the display, the PC will pop up the new disk folder, copy the subfolder of the same name of the project just generated /default/ to the “raw” folder of the display storage directory.

3、Hardware Connection And Command Testing

Verify the commands to be used before programming. Connect as shown in Figure (9), check the feedback from STONE, and verify the validity of the commands through the serial assistant.

This project involves five types of controls:

  • button
  • label
  • text_selector
  • gauge_pointer
  • checkbox

We will test and verify them one by one.

Figure (9) Serial Assistant test adapter board jumper diagram
Figure (9) Serial Assistant test adapter board jumper diagram

Button Related:

0x1001  button key-value actively sent down

Key-value (last byte of the data section):

0x01  press down button pressed

0x02  press up button release (button complete trigger click event)

Example:

The parameter screen Start button (name = b11 ) is pressed to actively issue the command.

ST<0x10 0x01 0x00 0x04 b11 0x01>ET

The serial assistant returns hexadecimal data:     Verify OK

53 54 3C 10 01 00 04 62 31 31 01 3E 45 54 5C 0B

Button release (completion of button click action) active command —- as a way to 62 31 31 02 decode feasible!

ST<0x10 0x01 0x00 0x04 b11 0x02>ET

The serial assistant returns hexadecimal data:  Verify OK

53 54 3C 10 01 00 04 62 31 31 02 3E 45 54 18 0B

Note: Button b11 (ASCII code 0x62 0x31 0x31).

Label Related:

set_text  Set the text displayed by the label

Example:

Set text: (min countdown name = l21)

ST<{“cmd_code”: “set_text”, “type”: “label”, “widget”: “l21”, “text”: “29”}>ET Verify the top screen OK

Text Selector Related:

0x1081  text selector value is sent  (int type Active posting: posted as soon as the selector is adjusted)

Data format:

value: the last four bytes of the data section

Example: (delayed boost time min selector control name = ts12, options: 1-60, current 16, reselect when 20)

The hexadecimal data received by the serial assistant is.

53 54 3C 10 81 00 08 74 73 31 32 00 00 00 14 3E 45 54 F8 4E OK

The screen actively gives instructions viz.

ST<0x10 0x81 0x00 0x08 ts12 0x00 0x00 0x00 0x00 0x14 >ET   ts11 current value:20 = 0x14

Gauge_pointer Related:

set_angle  Sets the rotation angle of the pointer (int type)

Example: (barometer pointer name = gp1)

Set the pointer angle parameter: the following are verified OK

ST<{“cmd_code”: “set_angle”, “type”: “gauge_pointer”, “widget”: “gp1”, “angle”:-140}>ET

ST<{“cmd_code”: “set_angle”, “type”: “gauge_pointer”, “widget”: “gp1”, “angle”:30}>ET

ST<{“cmd_code”: “set_angle”, “type”: “gauge_pointer”, “widget”: “gp1”, “angle”:30}>ET

ST<{“cmd_code”: “set_angle”, “type”: “gauge_pointer”, “widget”: “gp1”, “angle”:130}>ET pointer”, “widget”: “gp1”, “angle”:130}>ET

ST<{“cmd_code”: “set_angle”, “type”: “gauge_pointer”, “widget”: “gp1”, “angle”:-110}>ET

ST<{“cmd_code”: “set_angle”, “type”: “gauge_pointer”, “widget”: “gp1”, “angle”:0}>ET

ST<{“cmd_code”: “set_angle”, “type”: “gauge_pointer”, “widget”: “gp1”, “angle”:270}>ET

Checkbox Related:

The multi-select button is actively sent down when the status changes.

0x1020  Active posting after check button value change

Example: (delayed boost selector knob name = cb1)

The “unchecked” serial assistant received when the value changed.

53 54 3C 10 20 00 04 63 62 31 00 3E 45 54 AC 46

Equivalent to a directive:

ST<0x10 0x20 0x00 0x0D cb1 0x00 >ET  Unchecked

When the value is changed, the “selected” serial assistant receives.

53 54 3C 10 20 00 04 63 62 31 01 3E 45 54 50 47

Equivalent to a directive:

ST<0x10 0x20 0x00 0x0D cb1 0x01 >ET  selected

With the above command tested, the next step is to program the function with confidence. Of course, the first thing is still the hardware connection. We are using the ESP32 development board to implement the communication with the STONE serial screen.

As in Figure (10), the NodeMCU-32S development board TX0, RX0, and GND is required to connect with the STONE screen adapter board corresponding to complete the HMI information interaction.

STONE screen interface is 232 signals, through the adapter board into the MCU interface needs TX, and RX signals, in order to level the match.

Figure (10) on the left is the NodeMCU-32S board, blue (TX0), red (RX0) wire connected to the adapter board jumper position (next to the blue jumper removed), black even GND.

Figure (10) NodeMCU-32S development board and adapter board communication connection diagram
Figure (10) NodeMCU-32S development board and adapter board communication connection diagram

4、Debug Code

This project focuses on the decoding of buttons, multi-selector buttons, and text selectors, as well as the algorithm of the barometer pointer drive, countdown timer, and delayed boost.

Start air pressure delay boost process, ESP32 board blue LED will flash prompt, barometer display interface air pressure pointer will simulate boost evenly turn to the target air pressure position (16cmH2O table with 160 instead), delay countdown will be dynamically displayed per second decreasing (for intuitive set 1min countdown, the actual use of the general set 15min – 60min).

The program code below the recording has been verified, please refer to the video for the operation effect.

/*
Frank for Sleep Ventilator in 2022.05.03
use ESP32 of NodeMCU-32s in arduino 1.8.13
use STONE HMI in shenzhen
int (-32768,32767) unsigned int(0,65535)
button:
start---"b11"---0x62 0x31 0x31
stop---"b12"---0x
text_selector:
pressure---"ts11"---0x74 0x73 0x31 0x31
delay time--"ts12"---
checkbox:
delay boost---"cb1"---0x63 0x62 0x31
label:
min---"l21"---
sec - "l22" -
gauge pointer:---"gp1"--
*/
//------Sleep Ventilator use----------2022.05.03------
int delayTimeMin = 1; //the min of delayed pressure boost
int delayTimeSec = 0;
int inPressure = 20; // cmH2O set
int nowPressure = 0; // now cmH2O
int start = 0; // 1 = start, 0 = stop
int dealyedPressure = 1; // 1 = selector, 0 = not delay
int minShow,secShow,pointerShow;
float m1,m2,m3;
int i1,i2,i3;
//------time++ use------
int timeON = 0; // 0 = off, 1 = ON
int ii = 0;
unsigned int time_1s=0;
unsigned int time_1m=0;
unsigned int time_1h=0;
int iii = 0;
int LED_blue = 2; // IO2, turn the LED on (HIGH is the voltage level)
void setup() {
Serial.begin(115200);
pinMode(LED_blue, OUTPUT);
}
void loop() {
int inChar;
// Read the information sent by the serial port and simply decode it:
if (Serial.available() > 0) {inChar = Serial.read();}
if (inChar == 0x62) // 2 pcs button
{
if (Serial.available() > 0){inChar = Serial.read();}
if (inChar == 0x31)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x31)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x02)
{
if(dealyedPressure == 1 && start == 0)
{
time_1s = 0;
time_1m = 0;
timeON = 1;
}
start = 1; //62 31 31 02 is start ok!
}
} else if (inChar == 0x32)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x02)
{
start = 0; //62 31 32 02 is stop ok!
timeON = 0;
}
}
}
}else if(inChar == 0x63) // 1 pcs checkbox
{
if (Serial.available() > 0){inChar = Serial.read();}
if (inChar == 0x62)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x31)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x00)
{
dealyedPressure = 0; // 0 = not delay
timeON = 0;
}else if(inChar == 0x01)
{
dealyedPressure = 1; // 1 = selector,
if(start == 1)
{
time_1s = 0;
time_1m = 0;
timeON = 1;
}
}
}
}
}else if(inChar == 0x74) //2 pcs text selector
{
if (Serial.available() > 0){inChar = Serial.read();}
if (inChar == 0x73)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x31)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x31) // 74 73 31 31 is proessure
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x00)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x00)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x00)
{
if (Serial.available() > 0){ inChar = Serial.read();}
inPressure = inChar;
}
}
}
}else if (inChar == 0x32) // 74 73 31 32 is delay min
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x00)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x00)
{
if (Serial.available() > 0){ inChar = Serial.read();}
if (inChar == 0x00)
{
if (Serial.available() > 0){ inChar = Serial.read();}
delayTimeMin = inChar;
}
}
}
}
}
}
}
//---------show------- min-------- sec---------
if(time_1m < delayTimeMin)
{
minShow = delayTimeMin - time_1m - 1;
secShow = 59 - time_1s;
}else
{
timeON = 0;
}
if(start == 1 && dealyedPressure == 1)
{
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l21\",\"text\":\"");
Serial.print(minShow);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l22\",\"text\":\"");
Serial.print(secShow);
Serial.println("\"}>ET");
}else //stop or dealyedPressure == 0
{
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l21\",\"text\":\"");
Serial.print(delayTimeMin);
Serial.println("\"}>ET");
Serial.print("ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"l22\",\"text\":\"");
Serial.print(delayTimeSec);
Serial.println("\"}>ET");
}
//-----------show------pressure--------
if(dealyedPressure == 0 || timeON == 0)
{
pointerShow = inPressure*17 -145;
}else
{
i1 = time_1m*60 + time_1s;
m1 = (float)delayTimeMin*60.0;
m2 = (float)i1/m1;
m3 = (float)inPressure*17.0*m2;
pointerShow = int(m3) -145;
}
if(start == 1)
{
Serial.print("ST<{\"cmd_code\":\"set_angle\",\"type\":\"gauge_pointer\",\"widget\":\"gp1\",\"angle\":");
Serial.print(pointerShow);
Serial.println("}>ET");
}else //stop
{
Serial.println("ST<{\"cmd_code\":\"set_angle\",\"type\":\"gauge_pointer\",\"widget\":\"gp1\",\"angle\":-145}>ET");
}
//------------------time ++ --------begin---------
if(timeON == 1)
{
delay(10);
ii += 1;
if(ii > 29) //sec++
{
ii = 0;
time_1s += 1;
if(time_1s >= 60) //min++
{
time_1s = 0;
time_1m += 1;
if(time_1m >= 60) //hour++
{
time_1m = 0;
time_1h += 1;
}
}
if(iii == 0){
iii = 1;
digitalWrite(LED_blue, HIGH); // turn the LED on (HIGH is the voltage level)
}else
{
iii = 0;
digitalWrite(LED_blue, LOW); // turn the LED off by making the voltage LOW
}
}
}
//------------------time ++ --------end---------
}

Decoding Instructions.

The barometer pointer drive algorithm uses operations between integer and floating-point numbers, and care needs to be taken to use the following operation format specification, otherwise, you will not get the correct result.

Figure (11) Rules for floating-point and integer arithmetic
Figure (11) Rules for floating-point and integer arithmetic

Article Source:

https://www.stoneitech.com/stone-tft-screen-ventilator-screen-project/

Video Of The HMI Of The Ventilator Screen