B4J Tutorial [IoT][ESP8266]B4J/B4A/B4i & ESP8266 Basic: Example thread

What is a ESP8266?

It's a small Basic programmabe microcontroller with Wifi, TCP/IP stack plus server, GPIO's and... it's unbelievable cheap. For about 3€ you get it as a bulk version which you have to solder. For 5 more you get this one with a micro usb UART adapter and a voltage converter (5V will kill it).

http://www.ebay.co.uk/itm/NEW-NodeM...842030?hash=item35f6f9f12e:g:CVkAAOSwnipWU62m

Usually it comes with a basic os which you can connect to via a serial terminal like Putty. Here you can activate the Wifi and other things by AT commands. But we skip this here. There is a better solution: ESP8266 Basic.

You can run basic programs on the ESP which offers many functions for GPIO's and it's acts like a server & handles get requests. So we can call it via HttpUtils :)

Step 1:

Go to http://www.esp8266basic.com/flashing-instructions.html and download the flasher.exe. It's simple Windows-UI program which brings the OS to flash with it. No need to search for os-images or to load 6 files which is very annoying.

You can see the soldering needed on cheaper devices. Buying the USB one is totally worth it. Plug & Play. You will only need to connect a simple USB cable to your laptop/pc.

Step 2:

Connect the ESP8266 to a USB port on your laptop/pc and let it recognize the device (my WIN 10 did it all alone). Wait some seconds. Check it under System -> Devices/Drivers. Take a look at the COM-Port (usually it's #3). If the recognition fails then check the www for drivers for it.

Step 3 (important):

Disconnect it!

Step 4:

Start the flasher.exe. Select the COM-port (usually 3) and select th memory size. 1M did it for me. Don't flash yet!

Step 5:

The ESP ist still disconnected. It has a reset and a flash button (another advantage to the cheap ones). So press & hold(!) the flash button and connect the usb cable to power it up. Hold the button for 5 secs (maybe it has to be pressed just for e millisecond - I didn't try) and release it.

Step 6:

Wait some seconds after releasing the button and press "Firmware Flash". You should now see a small led flashing while the firmware is transmitted. It takes about 30 secs. A new window shows the success (a dotted line). Close the flasher and press the reset button on the ESP board.

http://www.esp8266basic.com/flashing-instructions.html

Step 7:

After the reset the ESP boots for the first time and set's itsself to a WiFi access point. Just connect to "ESP", start your browser and type "192.168.4.1" to access the ESP's gui.

You will see this:

B4X:
[ VARS ] [ EDIT ] [ RUN ] [ SETTINGS ] [ FILE MANAGER ]
ESP Basic 2.0.Alpha 20

Step 8:

As we want to integrate it into out network at home we have to do a small configuration. Click on "Settings":

settings.JPG


Looks quite like your router's config page. Fill out the station mode section (your router's name & Wifi pw). Click on "Save" and reset it. Please set a login pw on the ESP later (for the first steps it might be annoying to do a login every time while playing with it).

If you like to start a program automatically after the boot is completed (autostart), you can enable it here. The name must be "default.bas". Use it later if you are more experienced.

Log in to your router and check if the ESP is connected to your Wifi network. Get it's ip-address.

Step 9:

Get back to your browser and start the ESP's UI again by typing it's WiFi ip address.

Step 10:

Select "Edit" to get to the source editor. It is very simple and stores the programs as files in the file system.

edit.JPG


Step 11:

From the ESP8266's webpage I've taken this example to set/retrieve the status of the GPIO pins:

B4X:
msgbranch [mybranch]
print "You can send msgs to the esp and do things based on accessing a URL"
wait
[mybranch]
MyReturnMsg = "Not a valid msg received"
msgget "pin" pinNo
msgget "stat" pinStatus
msgget "action" pinAction
if pinAction == "po" then gosub [po.pin]
if pinAction == "pi" then gosub [pi.pin]
if pinAction == "pwo" then gosub [pwo.pin]
if pinAction == "pwi" then gosub [pwi.pin]
if pinAction == "ai" then gosub [ai.pin]
print "Done with return code"
msgreturn MyReturnMsg
wait

[po.pin]
po pinNo pinStatus
MyReturnMsg = "good"
return

[pi.pin]
pi pinNo MyReturnMsg
return

[pwo.pin]
pwo pinNo pinStatus
MyReturnMsg = "good"
return

[pwi.pin]
pwi pinNo MyReturnMsg
return

[ai.pin]
ai MyReturnMsg
return

A "msgbranch" is some sort of an event. A given Sub (here "mybranch") will be called if a message arrives.

"msgget" is used to get the values from a get request.

The full command set/language reference can be found here: https://docs.google.com/document/d/1NMZvnnjZ5XNzkykINgYS_Ql6mQ3nJEAzYudbmScdiIg/pub#h.4eyo3bggeuan

As you can see it offers a lot of functions, even graphics.

Copy the lines to the editor and press "Save". Click on "Run" to start it. In another tab use this get request to control the gpio's:

B4X:
192.168.xxx.xxx/msg?pin=2&stat=1&action=po

A nice request we can handle with a simple B4A/B4J app:

B4X:
'Non-UI application (console / server application)
#Region  Project Attributes
    #CommandLineArgs:
    #MergeLibraries: True
#End Region

Sub Process_Globals
    Public ServerName, Pin, Stat, Action As String
End Sub

Sub AppStart (Args() As String)

    ServerName="http://192.168.178.37/"
    Pin="1"
    Stat="1"
    Action="pwi"

    'http://192.168.178.37/msg?pin=2&stat=1&action=po

    Dim ESP8266 As HttpJob
    ESP8266.Initialize("ESP8266", Me)
    ESP8266.Download2(ServerName & "msg?",  _
            Array As String("pin", Pin,"stat", Stat,"action", Action ))
  
    StartMessageLoop

End Sub


Sub JobDone(Job As HttpJob)

    If Job.Success Then
        Dim res As String
 
        res = Job.GetString
        Log("Response from ESP8266: " & res)
 
        If res.Contains("good") Then
            'Do something...
        End If
 
    Else
        Log("Error: " & Job.ErrorMessage)
    End If
    Job.Release

End Sub

Hints:

Getting back to the Editor will end any program. So take care to run it again (or you'll get some other message from the ESP)

Place a SPACE between each word, etc of a line:

Good: if a == 4 then ....
Bad: if a==4 then
 
Last edited:

KMatle

Expert
Licensed User
Longtime User
Another one:

The ESP8266 can send http get requests by:

B4X:
print wget("192.168.178.23/esp/test.php?Name=Peter&Age=55")

php-Script:

B4X:
<?php
$name=$_GET["Name"];
$age=$_GET["Age"];

print $name . " is " . $age . " years old...";
?>

Output:

B4X:
Peter is 55 years old...
Done...
 

KMatle

Expert
Licensed User
Longtime User
Checking GPIO's by interrupt and if a change occurs call a php script (get request):

B4X:
st = 0
p = 2
Pi p st
print "ESP ist waiting for Pin " & p & " to change..."
interrupt p [gpio]
Wait
[gpio]
Pi p nst
print st & "/" & nst
print wget("192.168.178.23/esp/pin.php?Pin=2&Status=" & nst)
st = nst
wait

PHP:

B4X:
<?php
$pin=$_GET["Pin"];
$st=$_GET["Status"];
print "Back from PHP -> Pin: " . $pin . " has changed: " . $st;
?>

Just click on "Run" in the ESP's menu and refresh the browsers page to see the messages (or add some code to the php to store/use the data)



Known issue: A space is used to delimit the get request:

B4X:
wget("192.168.178.23/esp/pin.php?Name=Muller&Street=Muller Street)

will truncate the request after "Street=Muller". I've contacted the author to fix this.
 
Last edited:

KMatle

Expert
Licensed User
Longtime User
Check GPIO pin by interrupt and store the events into a MySQL database. The special chars äöüß are encoded correct except space which will be converted to a "+".

ESP-Basic program:

B4X:
dev = "ESP1"
st = 0
p = 2
Pi p st
print "ESP ist waiting for Pin " & p & " to change..."
interrupt p [gpio]
Wait
[gpio]
Pi p nst
if nst = 0 then
   url = "192.168.178.23/esp/pin.php?Action=Message&mfrom=" & dev & "&mto=System&mtype=1&mess=Door/Window opened"
   gosub [urlencode]
   print wget(url)
else
   url = "192.168.178.23/esp/pin.php?Action=Message&mfrom=" & dev & "&mto=System&mtype=2&mess=Door/Window closed"
   gosub [urlencode]
   print wget(url)
end if
st = nst
wait

[urlencode]
url = replace(url," ", "+")
print url
return

PHP:

B4X:
<?php

$host = "127.0.0.1";
$user = "homeauto";
$pw = "homeauto";
$db = "HomeAuto";

$con = mysqli_connect($host,$user,$pw) or die(mysqli_error());
mysqli_select_db($con,$db) or die(mysqli_error());
mysqli_query($con,"SET CHARACTER SET utf8");
mysqli_query($con,"SET NAMES 'utf8'");

$action=$_GET["Action"];

switch ($action) {
    Case "Message":
         $mfrom=$_GET["mfrom"];
        $mto=$_GET["mto"];
        $mtype=$_GET["mtype"];
        $mess=$_GET["mess"];
  
        $r = mysqli_query($con, "Insert into mess (st, mfrom, mto, mtype, mess) VALUES ('I', '$mfrom', '$mto', '$mtype', '$mess')") or die(mysqli_error());
        print $mess . "OK";
        break;

Case "GetMessages":
        $q = mysqli_query($con,"SELECT * FROM mess where mtype = '1' order by ts desc") or die(mysqli_error());
      
        $rows = array();
        while($r = mysqli_fetch_assoc($q))
        {
            $rows[] = $r;
        }
      
        $jsrows=json_encode($rows);
        print $jsrows;
        break;
  
default:
        print json_encode ("Error: Function not defined ->" . $action);
}

?>

Hardware:

Connect "D4" (= GPIO2) to a button and from the button to ground (the black square on the left :)) The USB cable is used for the power supply.

IMG_20160504_160925.jpg



Table (dump file, just import it via the phpadmin gui):

B4X:
-- phpMyAdmin SQL Dump
-- version 4.5.1
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Erstellungszeit: 04. Mai 2016 um 16:29
-- Server-Version: 10.1.10-MariaDB
-- PHP-Version: 5.6.15

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Datenbank: `homeauto`
--

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `mess`
--

CREATE TABLE `mess` (
  `nr` int(11) NOT NULL,
  `st` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
  `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `mfrom` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
  `mto` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
  `mtype` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
  `mess` varchar(2000) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Daten für Tabelle `mess`
--

INSERT INTO `mess` (`nr`, `st`, `ts`, `mfrom`, `mto`, `mtype`, `mess`) VALUES
(32, 'I', '2016-05-04 14:18:34', 'ESP1', 'System', '1', 'Door/Window opened'),
(33, 'I', '2016-05-04 14:18:34', 'ESP1', 'System', '2', 'Door/Window closed');

--
-- Indizes der exportierten Tabellen
--

--
-- Indizes für die Tabelle `mess`
--
ALTER TABLE `mess`
  ADD PRIMARY KEY (`nr`),
  ADD UNIQUE KEY `nr` (`nr`),
  ADD KEY `mto` (`mto`);

--
-- AUTO_INCREMENT für exportierte Tabellen
--

--
-- AUTO_INCREMENT für Tabelle `mess`
--
ALTER TABLE `mess`
  MODIFY `nr` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=34;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

Usage:

1. click on run to start the program (webbrowser)

2. press the button on the board

3. update the browser to see the output of the print commands (not needed)

4. take a look at the table:

Unbenannt.JPG
 

rwblinn

Well-Known Member
Licensed User
Longtime User
A first test after receiving a NodeMCU. Connected DHT11 sensor and send data via UDP to B4J UDP Client.
ESP8266 Basic is in Alpha Release, hope to see functionality like wpost (to send data to B4J Webserver), JSON (in the pipeline) etc.. This is a good read to get the latest on development, plus the documentation.
Really fun to play with this neat controller.

Screenshot UDP test after running ESP8266 Basic Code.
upload_2016-5-5_19-25-48.png


ESP8266 Basic Code
B4X:
'ESP8266 NodeMCU HowTo - Get Temperature and Humidity from DHT11 sensor
'Connection:
'DHT11 ---- ESP8266
'GND ------ GND
'VCC ------ 3.3v
'Signal --- D4

'Set the sensor model (DHT11) and pin (D4)
dht.setup(11, D4)

print "ESP8266 NodeMCU HowTo - Get Temperature and Humidity from DHT11 sensor"

'Get the temperature in celsius
celsius = dht.temp()
print "Temperature " & celsius & "C"

'Get the humidity
humidity = dht.hum()
print "Humidity " & humidity & "%"

'Send data to UDP client
udpwrite "192.168.0.4", 3661, "Temperature " & celsius & "C, Humidity " & humidity

B4J UDP Client
Attached - used Client1 for receiving data from the NodeMCU.


Thanks again for triggering this topic.
 

Attachments

  • B4JHowToUDPc2c.zip
    475.8 KB · Views: 437

KMatle

Expert
Licensed User
Longtime User
Really fun to play with this neat controller

Yep. I like the idea of the "all in one" idea of it. No need for an external sdk, libs, etc. Just input a few lines of code and have fun. And the price is unbeatable :D

A perfect device for B4x
 

rwblinn

Well-Known Member
Licensed User
Longtime User
For those interested, started to build a webpage about ESP8266 Basic including sample projects.
The sample projects include interaction with B4J in various ways (UI, Server).

Select from my homepage IoT > ESP8266 > ESP8266 Basic Experiments.
 

rwblinn

Well-Known Member
Licensed User
Longtime User
Explored further the integration between the ESP8266 and B4J.
This is an example of reading DHT11 sensor data from an ESP8266 , send the data (by ESP82266 Basic program) to a B4J server application which stores the data and displays in a Google Line Chart. Every time new data arrives at the B4J server, the Google Line Chart is automatic refreshed in the Webbrowser (fun watchin' it...). Again, this shows the power of B4J = few lines of code and magic happens :)

upload_2016-5-16_17-43-19.png
 

Attachments

  • esp8266basicdht11googlelinechart.zip
    15.4 KB · Views: 427
Top