ITCooky Recipes

Lets cooky it yammy things!

Orange PI PC as a Server in Armbian!

дата November 21, 2019

I has found an unfinished article, that’s why the Armbian is very old, but in that there are its advantages! I remade it and rewrote it a bit, and here is the server in Orange Pi Pc! Why this is a server? Because it is autonomous: it has a clock and can be connected to it directly, there is a safe power off, there is a temperature control of the processor with a fan and there is a screen with parameters as in real servers.

Just like that I upload an image from Armbian.com to Orange Pi Pc so as not to limit myself I made a special Orange Pi, by the way, the diagram is not as scary as it turned out in the photo.

Used to look like this



But I removed the bread board, cut the wires and soldered them to the plate, and it looks more beautiful now


Here is a diagram, the energy passes through the microUSB connector.

I usualy download the image for Orangte PI PC from here https://www.armbian.com/orange-pi-pc/ its the same with PC PC PLUS, it’s fine! But in the old kernel 3.4 the server assemblies are not there, but it had Armbian_5.25_Orangepipcplus_Debian_jessie_default_3.4.113

We write on the SD card: I use a bad Transcend 2 Gb without specifying speed and class. I don’t have an app to open the file in 7z in Ubuntu, so first I install it:
sudo apt-get install p7zip-full
We put everything in the desired folder and unzip it
7z e Armbian_5.25_Orangepipcplus_Debian_jessie_default_3.4.113.7z
Format the SD card any way you like, I do it through Gparted. And write on the card, I have the card in sde1
sudo dd bs=1M if=Armbian_5.25_Orangepipcplus_Debian_jessie_default_3.4.113.img of=/dev/sde

We inserted the card in Orange Pi Pc and voila, it works! After loading, you must enter the root name and password 1234, after that you must change the password and add a user, here everything is described http://docs.armbian.com/User-Guide_Getting-Started/ You must also reboot a few times to use the entire memory card.

Connect to wifi
Yes, it is not common for servers, but it is necessary for mobility. I insert one of those USB WiFi, the link does not work anymore, but the name is Мини USB адаптер wi-fi RTL 8188EUS Comfast CF-WU810N-1 adapter беспроводная точка доступа wi-fi USB WiFi adapter ключ WiFi adapter USB
This is an old Armbian, there is no armbian-config, so to connect to Wi-Fi, run
nmtui-connect
There is nothing to tell, everything is clear.

Here is an interesting bug was revealed. Wi-Fi was activated after the restart, but Armbian thought it was still on the cable, although there was no cable and because of this, the Internet did not work. I had to do
ifdown eth0

Safe shutdown (relatively, compared to pushin out the power cord, it is very safe)
The problem is that in OrangePi (so far) there is no piece of hardware that turns off the power. But you can turn off the operating system and then pull the cable. To understand that the operating system has shut down at this stage, I will use a Led.To communicate with GPIO you need to install WiringOP

cd /root
git clone https://github.com/zhaolei/WiringOP.git -b h3
cd WiringOP
chmod +x ./build
sudo ./build

Now turn on Led, go to
cd /root/WiringOP/examples/
and make file
vi powerled.c
with code

#include <stdio.h>
#include <wiringPi.h>
#include <unistd.h>
#define LED 2

int main (void)
{
  wiringPiSetup () ;
  pinMode (LED, OUTPUT) ;

for (;;)
  {
usleep(500);
if(digitalRead(LED) == 0)

  {
    digitalWrite (LED, HIGH) ;  // On
    delay (1000) ;
  }
}

  return 0 ;
}

Led is on pin 2. The script looks at its state, if it is off it turn it on and wait for 1000 milliseconds, well, it is not necessary to do it a thousand times a second!

CAUTION: C cycles load the processor for 100%, so i have to slow down usleep () (in milliseconds)

make
make ./powerled
and copy it to root folder
cp ./powerled /root
to run it on boot, we go to cron
crontab -e
And add that line

@reboot /root/powerled & > /dev/null

make update
apt-get update
We install ACPID … jm is not installed …
aptitude install acpid

This is where the old core 3.4 plus appears, in the new acpid it doesn’t work at all with the power button

Then we create
vi /etc/acpi/events/button_power
We write here

event=button/power
action=/sbin/shutdown -h now

We restart ACPID
/etc/init.d/acpid restart

Click the power button and OrangePi starts to turn off, this can be seen from the console. When the light goes out, all the services are already turned off and the core is in a panic, there are 10 seconds to disconnect the power cable, if you don’t disconnect it, Orange Pi will start boot again.

Unfortunately, I couldn’t make the Led blink after pressing the button, just a command in acpid, and if you put a link to the script there it doesn’t work well …

More about power
OrangePi has a very bad power connector, for a seemingly cheap model, the connector is unknown hmm is strange! And the USB chargers goes micro USB cable! Energy can be received by screwing a normal microUSB connector to OrangePi!

I bought ones called 10 шт. / Лот Micro USB к DIP-адаптер 5pin разъем PCB конвертер . Solder wires to GND and VBUS and in OrangePi connect them to first 5V and GND. So far, everything works from charging Samsung in 2A on a long cable.

OrangePi server access via USB cable
You can use a USB TTL converter, but I put the Arduino Nano inside, so I just need a USB cable. My Arduino Nano is a complete Chinese copy with the suitable USB chip, it has better support in terms of drivers in all operating systems, so it was called оригинал Nano 3.0 atmega328 мини-версия FT232RL импортные чипы поддержка жоддержа доддержа годдержа годдержева -кабель .

In Arduino Nano, you need to short-circuit GND and RESET and connect it to GND and TX, RX of OrangePi.

As I am in Ubuntu, I need to install
sudo apt install screen
We connect Arduino Nano, OrangePi must also be on!
We looked at where the connection stayed
dmesg | grep tty
it’s usually ttyUSB0 and we connect to it
sudo screen /dev/ttyUSB0 115200
It works strangely, at first nothing happens, then, whether you press once or several times the enter, a password request appears. In general, a good way to connect to the server without everything in the field.

We connect a DS3231 RTC clock
If there is Internet, Armbian sets the time himself, you just need to choose your time zone
dpkg-reconfigure tzdata

If there is no Internet, then time starts from the last to the shutdown. That is, off for half an hour, time is delayed half an hour.

Install i2c
apt-get install i2c-tools

We look where the clock appeared
i2cdetect -y 0
It’s here (a number that wasn’t before)

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3f 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --   

I already have something connected here, but I know the clock is 68, it must be revived by running

sudo echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device

A command to see the time
hwclock -r -f /dev/rtc1

A command write the system time on the clock (it must be done once after installing the battery to the clock)
hwclock -w -f /dev/rtc1

For the clock to start at boot and give the system time,
we must add
vi /etc/rc.local
that before the line exit 0

sudo echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
sudo hwclock -s -f /dev/rtc1

Auto start fan when CPU overheats
I wanted to integrate this into the screen program, but I couldn’t get a program from two different libraries, everything was too complicated in the MAKE file.

We are going to
cd /root/WiringOP/examples
make file
vi coolerstart.c
add code

#include <stdio.h>
#include <wiringPi.h>
#include <unistd.h>
#define LEDR 0
#define COOLER 1
#define WARNING_TEMP 55

int main (void)
{
  int number1;

  wiringPiSetup ();
  pinMode (LEDR, OUTPUT);
  pinMode (COOLER, OUTPUT);
 for (;;)
  {
usleep(1000);
FILE *in_file;


  in_file = fopen("/sys/class/thermal/thermal_zone0/temp", "r");
  if (in_file == NULL)
    {
        printf("Can't open file for reading.\n");
    }
    else
    {
        fscanf(in_file, "%d", &number1);
        fclose(in_file);
    }
 if ( number1 <= WARNING_TEMP)
{

    digitalWrite (COOLER, HIGH);   // Off
    digitalWrite (LEDR, LOW);   // Off

}
else
{
    digitalWrite (LEDR, HIGH);  // On
    digitalWrite (COOLER, LOW);  // On
    delay (150000);               // mS

}

  }
  return 0 ;
}

This is the path to the temperature file in Armbian /sys/class/thermal/thermal_zone0/temp

we compile
make coolerstart
And we run it in the background
./coolerstart & > /dev/null

To stop an app that works in the background is necessary
pkill coolerstart
That will stop everything that has coolerstart in the name

I start heating the CPU with the sysbench test, it is already installed in Armbian
sysbench --test=cpu --cpu-max-prime=20000 --num-threads=2 run

It works, it cools, it does not reach critical temperatures!

precompiled file copied to root folder
cp /root/WiringOP/examples/coolerstart /root/
go to cron
crontab -e
add this line (remove the previous one)
@reboot /root/coolerstart &> /dev/null

and it works

Connecting the lcm1602 screen
Download this library. It’s simple, in part of: you can’t erase a line just a whole screen, you can’t insert a symbol to an exact place only from the beginning of a line.
git clone https://github.com/wargio/liblcm1602.git
cd liblcm1602
make

The screen is in adress 3f you could see that in the result of the command i2cdetect -y 0
We write
vi test.c
here you have to change value 0x37 to 0x3f

i2c_dev = open_i2c(I2C_FILE_NAME, 0x3f);

Lo compilamos y lo arrancamos
make test
./test

it works

Let’s go ahead
To compile a file with our name, add the name of server_monitoring here
vi Makefile
we edit that line so that it looks like this

EXAMPLES=       server_monitoring test example example2 example3

We compile file
vi server_monitoring
Here is all the code

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "i2c.h"
#include "lcd.h"
#include <time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <unistd.h>
#define I2C_FILE_NAME "/dev/i2c-0"
#define TIME_TO_WAIT 2 

int main(){
int text=0;
int number1;
int number2;
clock_t last = clock();  
char txt[100];
   
// for Ip start     
 char ip_address_wlan[100];
 char ip_address_eth[100];
//for ip end


//for lcd start
 int i2c_dev;
    lcd lcd0;
    // 0x27 the address of the i2c device
    i2c_dev = open_i2c(I2C_FILE_NAME, 0x3f);
    if(i2c_dev <0){
       printf("Errore: %d\n", i2c_dev);
       return 1;
    }
lcd_init(&lcd0, i2c_dev);
    char vremya[100];
lcd_clear(&lcd0);
//for lcd end

for (;;)
  {


usleep(100);


clock_t current = clock();

//time loop start
    time_t now = time (0);
       strftime (vremya, 100, "%d%mY%y %H:%M:%S", localtime (&now));
lcd_print(&lcd0, vremya, 16,0);
//time loop end

if (current >= (last + TIME_TO_WAIT * CLOCKS_PER_SEC) && text == 0) {
int fd;
    struct ifreq ifr;    
fd = socket(AF_INET, SOCK_DGRAM, 0);
    ifr.ifr_addr.sa_family = AF_INET;
    memcpy(ifr.ifr_name, "wlan0", IFNAMSIZ-1);
    ioctl(fd, SIOCGIFADDR, &ifr);
    close(fd);
    strcpy(ip_address_wlan,inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
sprintf(txt, "w%s", ip_address_wlan);
lcd_print(&lcd0,"                ", 16,1);
lcd_print(&lcd0,txt, strlen(txt),1);

last = current;
text = 1;
}     

else if (current >= (last + TIME_TO_WAIT * CLOCKS_PER_SEC) && text == 1) {
int fd;
    struct ifreq ifr;    
fd = socket(AF_INET, SOCK_DGRAM, 0);
    ifr.ifr_addr.sa_family = AF_INET;
    memcpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
    ioctl(fd, SIOCGIFADDR, &ifr);
    close(fd);
   strcpy(ip_address_eth, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
sprintf(txt, "e%s", ip_address_eth);
lcd_print(&lcd0,"                ", 16,1);
lcd_print(&lcd0,txt, strlen(txt),1);
last = current;
text = 2;
}
else if (current >= (last + TIME_TO_WAIT * CLOCKS_PER_SEC) && text == 2) {

FILE *in_file;
  in_file = fopen("/sys/class/thermal/thermal_zone0/temp", "r");
if (in_file == NULL)
    {
        printf("Can't open file for reading.\n");
    }
    else
    {
        fscanf(in_file, "%d", &number1);
        fclose(in_file);
    }

char cmd[]="df -BM /  | tail -1 | awk '{print $4}'" ;
FILE* apipe = popen(cmd, "r");
 
if (apipe == NULL)
    {
        printf("Can't open file for reading.\n");
    }
    else
    {
        fscanf(apipe, "%d", &number2);
pclose(apipe);
    
}





sprintf(txt, "CPU:%dC S:%dMb", number1,number2);
lcd_print(&lcd0,"                ", 16,1);
lcd_print(&lcd0,txt, strlen(txt),1);
last = current;
text = 0;
}


}
close_i2c(i2c_dev);

return 0;
}

we compile
make server_monitoring
I copied the compiled file in the root directory
cp /root/liblcm1602/server_monitoring /root/
go cron
crontab -e
We add that line (delete the previous one)
@reboot /root/server_monitoringt & > /dev/null
reboot

As always, Google helped me to code. How in C take an IP i coped it from herehttps://www.includehelp.com/c-programs/get-ip-address-in-linux.aspx I did not understand how it works and how to configure it for my needs … it works so if all the interfaces are not connected, it will show something generic, if an interface is connected it shows its ip, if two are connected, both are shown, if one is disconnected , it also shows what was before … Ok!
or a line with temperature and free space, I also wanted to use C to calculate the free space, but it turned out to be too difficult, but you can put the usual console commands in C – and I did it.

The program consumes 60% of the CPU, apparently this is a payment for the time in seconds to update the screen 10 times per second. Later I will improve that consumption!

Disk backup and replacement
I have changed the “bad” SD card to a “good” SanDisk Ultra 16gb class 10 before that I measure the speed of the bad
mkdir /root/test
cd /root/test
sysbench --test=fileio --file-total-size=100Mb prepare
sysbench --test=fileio --file-total-size=100Mb --file-test-mode=rndrw --init-rng=on --max-time=300 --max-requests=0 run > test.io

result 186.63Kb/sec

We took out the SD card and inserted it into the computer in Ubuntu
I look where she appeared on my PC
and I do the backup
sudo dd if=/dev/sde of=./armbian_server_itcooky.img bs=1M

After that we take out the bad one, insert the good card and do
sudo umount /dev/sde1
sudo mkfs.vfat -I /dev/sde
sudo dd if=./armbian_server_itcooky.img of=/dev/sde bs=1M

Uhhh, Armbian has some kind of problem with changing the size of the cards now, so with the size of the image I do the same test.
The result is 1.202Mb/sec
UPD: We rewrite the fan controller and the information screen in Node.js
Apparently, all C programs consume 80% of the CPU. I noticed that the Node-Red monster doesn’t eat anything at all, but what happens if I write everything in Node.js.

First install nodejs
go here
cd /root
and
curl -sL https://deb.nodesource.com/setup_9.x | bash -
apt-get install -y nodejs

We put a module that will allow you to execute console commands ennode.js
npm i node-cmd
It is also necessary to compile a program for the screen to send text to the screen from the console. liblcm1602 updates the information by deleting the entire screen, this leads to blinking. So take another library that can update line by line, and also turn off the screen completely. But it places the cursor at the end; I will remove it by adding additional spaces to the line (stupidly). It is also important to update the screen from a only one place in the program, and due to asynchrony (so I decided), if they execute the update command from different places in the program, they delete each other.

cd /root
git clone https://github.com/bitbank2/LCD1602.git
cd LCD1602
make
cp main.c mainOLD.c

Add to main.c
vi main.c
this

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <lcd1602.h>

int main(int argc, char **argv)
{
int rc;
        rc = lcd1602Init(0, 0x3f);
        if (rc)
        {
                printf("Initialization failed; aborting...\n");
                return 0;
        }
int s = *(argv[2]) -'0' -1;

lcd1602SetCursor(0,s);
        lcd1602WriteString(argv[1]);
//      lcd1602Control(1,0,1); // backlight on, underline off, blink block on
//      getchar();
//      lcd1602Shutdown();
return 0;
} /* main() */

For my screen change rc = lcd1602Init (0, 0x3f);
– 0 is due to which screen, is in 0 of i2c
– 0x3f is your adress

compil
make -f make_demo
and copy to root
cp ./demo /root/demo

make
vi /root/server_monitoring.js
add

var cmd=require('node-cmd');
var sec = 61;
var min = 0;
var hour = 0;
var day = 0;
var month =0;
var year = 0;
text2 = "Booting...      ";
textn = 1;
cputemp = 0;
cputempwar = 45;
cputemptime = 60;  //in 0,5 sec
cputimer = 0;

function coolercpu () {
cmd.get(
        '/bin/cat /sys/class/thermal/thermal_zone0/temp',
        function(err, data, stderr)
{ cputemp = data.replace(/[^0-9]+/, '');

if (cputemp > cputempwar) {
cmd.get(
        'gpio read 1',
        function(err, data, stderr){
  if (data == 1) {
textn = 4;
cmd.get(
`
         gpio mode 0 out
         gpio write 0 on
         gpio mode 1 out
         gpio write 1 off
`,
        function(err, data, stderr){
 cputimer= cputemptime;

});
}
;});

} else {
 cmd.get(
        'gpio read 1',
        function(err, data, stderr){
if (data == 0 && cputimer > 0) {
cputimer = cputimer - 1;
};

  if (data == 0 && cputimer <= 0) {
 cmd.get(
`
         gpio write 0 off
         gpio write 1 on 
`,
        function(err, data, stderr){
textn = 5; 
});
};});
};
});
};
setInterval(coolercpu, 500);


function ledon(){ 
    cmd.get(
        'gpio read 2',
        function(err, data, stderr){
  if (data == 0) {
            
cmd.get(
        `gpio mode 2 out
         gpio write 2 on`,
        function(err, data, stderr){
});};
});
};
setInterval(ledon, 1000);

//start screen
function screen(){
var date = new Date();
  if ( date.getSeconds() != sec ) {
sec = date.getSeconds();
sec = (date.getSeconds() <  10 ? "0" : "") + date.getSeconds();
hour = (date.getHours() < 10 ? "0" : "") + date.getHours();
min = (date.getMinutes() < 10 ? "0" : "") + date.getMinutes();
year = date.getFullYear().toString().substr(-2); 
year = (year < 10 ? "0" : "") + year;    
month = date.getMonth() + 1;
month = (month < 10 ? "0" : "") + month;
day = (date.getDate() < 10 ? "0" : "") + date.getDate();


//cmd.run('/root/example2 "' + day + month + 'Y' + year + ' ' + hour + ':' + min + ':' + sec + '" "' + text2 + '"');
cmd.run('/root/demo "' + day + month + 'Y' + year + ' ' + hour + ':' + min + ':' + sec + '" 1&&/root/demo "'+ text2 + '" 2');

};
};
setInterval(screen, 10);

function textforscreen(){
switch (textn) {
case 1:
textn = 2;
cmd.get(
'/sbin/ip addr list wlan0 |/bin/grep "inet " |/usr/bin/cut -d\' \' -f6|/usr/bin/cut -d/ -f1',
        function(err, data, stderr){
data = data.substring(0, data.length - 1); 
if(data !== null && data !== '') {
text2 = "w" + data + "          ";
} else {
textforscreen();
};
});
break;
case 2:
textn = 3;
cmd.get(
'/sbin/ip addr list eth0 |/bin/grep "inet " |/usr/bin/cut -d\' \' -f6|/usr/bin/cut -d/ -f1',
        function(err, data, stderr){
data = data.substring(0, data.length - 1);
if(data !== null && data !== '') {
text2 = "e" + data + "          ";
} else {
textforscreen();
};
});
break;
case 3:
cmd.get(
'/bin/df -BM /  | /usr/bin/tail -1 | /usr/bin/awk \'{print $4}\'',
        function(err, data, stderr){
data = data.substring(0, data.length - 1);
text2 = "CPU:" + cputemp + "C S:" + data + "     ";
textn = 1;
});
break;
case 4:
text2 = "Cooler on  " + cputemp + "C       ";
textn = 3;
break;
case 5:
text2 = "Cooler off " + cputemp + "C       ";
textn = 3;
break;
}
};

setInterval(textforscreen, 3000);

To run on boot you have to install pm2
npm i pm2 -g
run it
pm2 start server_monitoring.js --name Server-mon
and this make him run on boot
pm2 startup
pm2 save

reboot
And it works, from the advantages, the processor load decreased, the thing is that there was a flickering of the screen but I already corrected it!

What does the program and functions do?
coolercpu – take the processor temperature with a console command, assign it to a variable (it will be needed later). If the temperature is higher than 45, then if the fan pin is off (it is inverted due to the transistor, it is determined to be on), it turns on, and the variable that determines what text to display on the screen gives a value of 5: there the text is lit with: fan status and temperature value. And also the temperature figure is cleaned of garbage, which sticks when you take it from a file, JS doesn’t care (C would make me a scandal for that) it works just like that, but when it is shown on the screen, an artifact appears in the end, therefore, all non-digits are removed from variable cputemp.

ledon – thats speeks by it self

screen – This is the screen, the screen is updated once per second, it takes time, if the seconds have changed, it is updated. Shows the date and one of the 5 texts. The time is checked if the numbers are less than 10 before adding the zero in front.

textforscreen – These are the texts that are changed every 3 seconds. 1 and 2 take an IP, some garbage is also put at the end, so the last symbol is removed. If there is no IP, then the next value is determined by the variable and the function starts on its own … just like the BASIC GO TO command that I miss a lot in modern languages. Because of that, all texts remain on the screen for 3 seconds, if it were not for the empty IP, the previous text would stay longer.

We add buttons to Orange Pi Pc in Node.Js and WiringOP
It seems simple, and it’s simple, but no. Arduino (in the microcontroller, in the FPGA even more) would manage with his eyes closed, and for any CPU it is an impossible task. The OrangePi processor updating the status of pins every 10 milliseconds consumes 100% of its power, however I will do it every 150mils … However, the CPU does not try to distribute the load with the 4 cores, Node.js can not run applications in a specific kernel, only in pm2 cluster mode, but it will run the same application in all cores, useful only for the web.

The button is on pin 5 and 6, the buttons have the top and bottom – beware of that!

There is a module to work with GPIO for Node.jshttps://www.npmjs.com/package/orange-pi-gpio but if you look at him, he does the same, send console commands to WiringOP, you can do it without him.

Here is a program just to check buttons and your fingers

const exec = require('child_process').exec;
n1 = 0;
p1 = 0;
n2 = 0;
p2 = 0;
once = 0;

if (once == 0)
{
cmd('gpio mode 5 in&&gpio mode 5 up');
cmd('gpio mode 6 in&&gpio mode 6 up');
console.log('Pins Ready');
once = 1;
};

function cmd(command) {
        return new Promise((resolve, reject)=> {
            exec(command, (error, stdout, stderr) => {
                if (error) {
                    reject(error);
                }
                resolve(stdout);
            });
});};


function button () {
cmd('gpio read 5')
.then((state)=>{
if (state == 0) {
n1 = n1 + 1;
console.log('5 count: %d', n1);
}
else { 
if (n1 > 0 ) {
p1 = p1 + 1;
if (p1 >= 3 ) {
n1 = 0;
p1 = 0;
console.log('5 none: %d', n1);
};};};});
cmd(`gpio read 6`)
.then((state)=>{
if (state == 0) {
n2 = n2 + 1;
console.log('6 count: %d', n2);
}
else {
if (n2 > 0 ) {
p2 = p2 + 1;
if (p2 >= 3 ) {
n2 = 0;
p2 = 0;
console.log('6 none: %d', n2);
};};};});
setTimeout(button, 150);
};
setTimeout(button, 10);

make file
vi button.js
and run
node ./button.js

The fingers, of each one, are almost the same and here you can see how they work with buttons in real conditions. You can increase the frequency of polling buttons in a row, reducing the number
setTimeout(button, 150);
It is better to use setTimeout, instead of setInterval, so that each button wait cycle begins after the end of the previous one. When you capture a pressed button, print one, otherwise, print zero and both should be clear, depending on the speed of the survey.

Cmd just creates a process and puts a console command there. The result of executing this function is not a response or a number, but a state: the state “I promise to answer” (Promise), therefore, to claim the answer, the next line is then. I didn’t quite understand how it works, but everything is asynchronous, but very synchronous: if each of those functions had its own identifier and you could expect an answer according to the then if … otherwise, everything seems to be synchronous, but it is asynchronous .

For the screen, I rewrite the screen output again
I put in в main.c

cd /root/LCD1602
vi main.c

eso

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <lcd1602.h>

int main(int argc, char **argv)
{
int rc;
        rc = lcd1602Init(0, 0x3f);
        if (rc)
        {
                printf("Initialization failed; aborting...\n");
                return 0;
        }
int b = *(argv[3]) -'0';
if (b != 0) {
lcd1602SetCursor(0,0);
        lcd1602WriteString(argv[1]);
lcd1602SetCursor(0,1);
        lcd1602WriteString(argv[2]);
} else {
lcd1602Shutdown();
};
return 0;
} /* main() */

compil
make -f make_demo
copy to root
cp ./demo /root/demo

And here is the new code with buttons. Pressing the left button, I turn off the screen. Pressing the right button turns off / on the rotation of the line with information. When the fan is turned on, the screen turns off, it seems that they lack enough electricity together, sometimes it even freezes. One more line of information was added. The processor is loaded at 35% -50% the minimum I could achieve …

var sec = 61;
var min = 0;
var hour = 0;
var day = 0;
var month =0;
var year = 0;
text2 = "Booting...      ";
textn = 1;
cputemp = 0;
cputempwar = 45;
cputemptime = 60;  //in 0,5 sec
cputimer = 0;
backlight = 1;
screenloop = 1;
screentimer = 5;
t = 0;
n1 = 0;
p1 = 0;
n2 = 0;
p2 = 0;
const exec = require('child_process').exec;
once = 0;


function cmd(command) {
        return new Promise((resolve, reject)=> {
            exec(command, (error, stdout, stderr) => {
                if (error) {
                    reject(error);
                }
                resolve(stdout);
            });
});};


if (once == 0)
{
cmd('gpio mode 5 in&&gpio mode 5 up');
cmd('gpio mode 6 in&&gpio mode 6 up');
cmd('gpio mode 0 out&&gpio mode 1 out&&gpio mode 2 out');
once = 1;
};


function button () {

cmd('gpio read 5')
.then((state)=>{
if (state == 0) {
n1 = n1 + 1;
}
else {
if (n1 > 0 ) {
p1 = p1 + 1;
if (p1 >= 3 ) {
if (n1 >= 1&& n1 <= 10){
if (screenloop == 1)
{
screenloop = 0;
t = 0;
}
else
{
screenloop = 1;
t = screentimer;
};
};

n1 = 0;
p1 = 0;
};};};});

cmd('gpio read 6')Ощеф
.then((state)=>{
if (state == 0) {
n2 = n2 + 1;
}
else {
if (n2 > 0 ) {
p2 = p2 + 1;
if (p2 >= 3 ) {

if (n2 >= 1&& n2 <= 10){
if (backlight == 1)
{backlight = 0;}
else
{backlight = 1;};

};

n2 = 0;
p2 = 0;
};};};});

setTimeout(button, 150);

};
setTimeout(button, 1000);





function coolercpu () {
cmd ('/bin/cat /sys/class/thermal/thermal_zone0/temp')
     .then((state)=>{ 
cputemp = state.replace(/[^0-9]+/, '');

if (cputemp > cputempwar) {
cmd ('gpio read 1')
    .then((state)=>{ 
  if (state == 1) {
textn = 100;
cmd('gpio write 0 on&&gpio write 1 off');
cputimer= cputemptime;
backlight = 0;

};
});

} else {
cmd ('gpio read 1')
.then((state)=>{
if (state == 0 && cputimer > 0) {
cputimer = cputimer - 1;
};

  if (state == 0 && cputimer <= 0) {
cmd('gpio write 0 off&&gpio write 1 on');        
backlight = 1;
textn = 101; 
};});};

});
setTimeout(coolercpu, 500);
};

setTimeout(coolercpu, 500);


function ledon(){ 
  
cmd('gpio read 2')
.then((state)=>{

if (state == 0) {
cmd('gpio write 2 on');            

};});};
setInterval(ledon, 1300);

//start screen
function screen(){

if (backlight !=3) {
var date = new Date();
  if ( date.getSeconds() != sec ) {
sec = date.getSeconds();
sec = (date.getSeconds() <  10 ? "0" : "") + date.getSeconds();
hour = (date.getHours() < 10 ? "0" : "") + date.getHours();
min = (date.getMinutes() < 10 ? "0" : "") + date.getMinutes();
year = date.getFullYear().toString().substr(-2); 
year = (year < 10 ? "0" : "") + year;    
month = date.getMonth() + 1;
month = (month < 10 ? "0" : "") + month;
day = (date.getDate() < 10 ? "0" : "") + date.getDate();


//cmd.run('/root/example2 "' + day + month + 'Y' + year + ' ' + hour + ':' + min + ':' + sec + '" "' + text2 + '"');
cmd('/root/demo "' + day + month + 'Y' + year + ' ' + hour + ':' + min + ':' + sec + '" "'+ text2 + '" ' + backlight);
if (backlight == 0) { 
backlight = 3;
};

};
};
setTimeout(screen, 30);
};
setTimeout(screen, 50);

function textforscreen(){
switch (textn) {
case 1:
cmd('/sbin/ip addr list wlan0 |/bin/grep "inet " |/usr/bin/cut -d\' \' -f6|/usr/bin/cut -d/ -f1')
.then((state)=>{
status = state.substring(0, state.length - 1);
//status = state;
if(status !== null && status !== '') {
text2 = "w" + status + "          ";
if (screenloop == 1){
if (t >= screentimer)
{textn = 2;
t = 0;
} else {
t = t + 1;
};
};
} else {
textn = 2;
textforscreen();
};
});
break;
case 2:
cmd('/sbin/ip addr list eth0 |/bin/grep "inet " |/usr/bin/cut -d\' \' -f6|/usr/bin/cut -d/ -f1')
.then((state)=>{
status = state.substring(0, state.length - 1);
if(status !== null && status !== '') {
text2 = "e" + status + "          ";
if (screenloop == 1){
if (t >= screentimer)
{textn = 3;
t = 0;
} else {
t = t + 1;
};
};

} else {
textn = 3;
textforscreen();
};
});
break;
case 3:
cmd('/bin/df -BM /  | /usr/bin/tail -1 | /usr/bin/awk \'{print $4}\'')
.then((state)=>{
//status = state.substring(0, state.length - 1);
status = state;
text2 = "CPU:" + cputemp + "C S:" + status + "Mb     ";
});
if (screenloop == 1){
if (t >= screentimer)
{textn = 4;
t = 0;
} else {
t = t + 1;
};
};
break;

case 4:
cmd('/bin/cat /proc/loadavg | /usr/bin/awk \'{print $1,$2,$3}\'')
.then((state)=>{
//status = state.substring(0, state.length - 1);
status = state;
text2 = "L:" + status + "     ";
if (screenloop == 1){
if (t >= screentimer)
{textn = 1;
t = 0; 
} else {
t = t + 1;
};
};


});
break;
case 100:
text2 = "Cooler on  " + cputemp + "C       ";
textn = 3;
break;
case 101:
text2 = "Cooler off " + cputemp + "C       ";

textn = 3;

break;
}
};

setInterval(textforscreen, 750);


Leave a Reply

Your email address will not be published. Required fields are marked *