28x2, 40x2 picaxe web server with ESP-01 and pi javascript

lbenson

Senior Member
Here is a picaxe web server, derived from hippy's code in post #28 in the thread, Where's the Wizard? https://picaxeforum.co.uk/threads/wheres-the-wizard.31896/ and hemi's suggestion of using javascript on a remote web server to actually build the html (on a pi, in this case). Per Electronics Learner 123's request in ESP8266 BASIC, this works on a phone (as well as a PC browser). https://picaxeforum.co.uk/threads/esp8266-basic.31895/

Here's a sample page.
webserver1.jpg
It's intended to illustrate turning on and of things (LEDs in this case, but could be relays) with radio buttons, and entering a numeric value. This value, for this page, is used to set a pwm level, with the pwm on or off based on a toggle setting, and ramping and fading of the pwm with a separate toggle. A series of 7 radio buttons allow 7 differently colored LEDs to be turned on or off (singly).
PCB, ESP, PWM module: webserver_PCB.jpg

I juggled some of hippy's code. By pre-setting the wifi information on the esp including the ip address, I was able to eliminate the Station.basinc file. I set up one #DEFINE area and three subroutines in the main program, 28esp8266, to 1) initialize data for this application; 2) write the HTML code which sets javascript variables and invokes the remote javascript; 3) process the URL that is returned from the browser (e.g., L=1&P=1&R=1&N=512&X=G); and 4) provide code which is run every 10 milliseconds while the program is otherwise idling waiting for a browser entry. The subroutines are called processURL, and mainUserLoop.

Here's the .bas program with the main user-modifiable routines:
Code:
' 28Esp8266
'===== Contents =====

'  InternetControlledPicaxe.bas
'  esp2866.basinc
'  Station.basinc
'  Server.basinc

'===== InternetControlledPicaxe.bas =====

#Picaxe 28X2
#No_Data
#No_Table
#terminal 19200
#com 4

#define testAPP1

; This program connects as a station to a 
; specific access point and then delivers
; HTML pages to anyone who request them.

symbol cQuote=34 ' double quote
symbol ledFlag=bit16
symbol pwmFlag=bit17
symbol fadeFlag=bit18
symbol rampDirectionFlag=bit19 ' 0 is down, 1 is up
' variables through w9 (b19:b18) used
symbol wPWMDuty=w10 ' b21:b20
symbol wPWMDutyNow=w11 ' b23:b22
symbol whichLED=b24 ' LED Pin # -- B1-B7
symbol i=b25
symbol chLED=b26 ' LED character value "P","R","Y","B","G","W","C","O"
       ' Pink, Red, Yellow, Blue, Green, White, Chartruese, Orange

; Define access point to connect to

'#Define SSID     "MySSID"
'#Define PASSWORD "MyPW"

; Define an ADC input channel if required

'#Define ADC_CHANNEL 0

; Define a LED output pin if required

'#Define LED_OUTPIN outpinB.7
'#Define LED_DIRPIN    dirB.7

#Define RAMStart 56
#IFDEF testAPP1
  symbol wordAdr10000=b48 ' used b48:b49:b50:b51:b52 for bintoascii destination; b53 not used
  high b.0,b.1,b.2,b.3,b.4,b.5,b.6,b.7
  pause 1000
  low b.0,b.1,b.2,b.3,b.4,b.5,b.6,b.7
  pause 1000
  for b4=B.0 to B.7: high b4: pause 500: low b4: next b4: pause 500 
  high b.0,b.1,b.2,b.3,b.4,b.5,b.6,b.7
  pause 1000
  low b.0,b.1,b.2,b.3,b.4,b.5,b.6,b.7
  wPWMDuty=0: wPWMDutyNow=0: pwmFlag=0: fadeFlag=0: ledFlag=1: whichLED=5: chLED="W"
  bintoascii wPWMDuty,b48,b49,b50,b51,b52
  if ledFlag = 1 then: high B.0: else: low B.0: endif
  if whichLED > 0 then: high whichLED: endif
#ENDIF

#Include "esp2866.basinc"

' #Include "Station.basinc"
#Include "Server.basinc"

putHTML:
  length= 300 ' 234 ' 437 ' 228 ' LB 200303

  ; Indicate we have a reply 

  Gosub SendReply_SendLength

  ; Send the actual reply
  ; Whether the <html><body>...</body></html>
  ; wrapping is required depends on the browser 
  ; which receives the data.
  ; Plain text can be returned which may be
  ; most appropriate if another PICAXE is to
  ; receive the data

  SerTxd( CR, LF, "Send reply - ", #length, " bytes", CR, LF )
  HSerOut 0, ( "<html><head><link type=text/css rel=stylesheet href=http://192.168.1.144:20780/s.css>" )
  pause 50
  HSerOut 0, ( "<link rel='icon' type='image/png' href='data:image/png;base64,iVBORw0KGgo='> " )
  pause 50
  HSerOut 0, ( "</head><body></body>" )
  pause 50

  HSerOut 0, ( "<script>var arrayCurVals = [" )  ' [1,1,0,133,",cQuote,"W",cQuote,"]
  pause 50
  HSerOut 0, ( #ledFlag,",",#pwmFlag,",",#fadeFlag,",",#wPwmDuty,",",cQuote,chLED,cQuote )
  pause 50
  HSerOut 0, ( "];</script>" ) ' 87 is "W"
  pause 50

  HSerOut 0, ( "<script src=http://192.168.1.144:20780/b5a.js></script></html>               " )
  pause 50
  return

processURL:
  SerTxd( CR, LF, "processURL", CR,LF )
  If Found("favicon.ico") Then
    SerTxd( CR, LF, "Got favicon.ico request", CR,LF )
    uptoPtr = savePtr
    Gosub CloseReply
    Return
  End If

  ptr=saveUrlPtr ' lb
  for i=1 to 24: sertxd(@ptrinc): next i: ptr=saveURLPtr: sertxd(cr,lf)
'#rem
  Do
    select @ptr  ' looking for "A"-"Z" 
                 ' e.g., L=1&P=1&R=1&N=512&X=G LED, PWM, Ramp/Fade, PWM DUTY, LED on B.1-5, B.7
      case "L": ptr=ptr+2 
        if @ptr="1" then : high B.0: ledFlag=1 : else : low B.0: ledFlag=0 : endif ' indicator LED
      case "R": ptr=ptr+2: if @ptr="1" then : fadeFlag=1 : else : fadeFlag=0 : endif ' ramp & fade PWM LED
      case "P": ptr=ptr+2: if @ptr="1" then : pwmFlag=1 : else : pwmFlag=0 : endif ' pwm LED on or off
      case "N": ptr=ptr+2: wPWMDuty=0
        do while @ptr <> "&" and @ptr <> " " 
          if @ptr => "0" and @ptr <= "9" then : wPWMDuty = wPWMDuty * 10 + @ptr - "0" : endif
          inc ptr
        loop
      case "X": ptr=ptr+2: lookdown @ptr,(0,"R","Y","B","G","W","C","O"),whichLED ' B.1-B.7
'        if whichLED = 6 then : inc whichLED : endif ' 20X2 B.6 becomes B.7
        low 1,2,3,4,5,6,7: high whichLED
        chLED=@ptr
        sertxd("Pin B.",#whichLED," HIGH",cr,lf)
    endselect
    ptr = ptr + 1
  Loop Until ptr => uptoPtr
  if pwmFlag = 1 then
    sertxd("Pwm turning on; duty=",#wPWMDuty," on pin ",#pPWM,cr,lf)
    if fadeFlag = 0 then ' turn on LED, max PWM
      pwmout pwmdiv16, pPWM, 249, wPWMDuty ' 500=50%, 1000=100% ' 1kHz    else
    else
      wPWMDutyNow=wPWMDuty
      pwmout pwmdiv16, pPWM, 249, wPWMDutyNow ' 500=50%, 1000=100% ' 1kHz    else
    endif
  else
    PWMOUT pPWM, OFF
  endif
'#endrem

  return

mainUserLoop: ' this is called every 10ms while idling
  if pwmFlag = 1 and fadeFlag = 1 then
    if rampDirectionFlag = 1 then ' ramp up
      wPWMDutyNow = wPWMDutyNow + 10
      if wPWMDutyNow > wPWMDuty then ' reverse direction
        wPWMDutyNow = wPWMDutyNow min 10 - 10
        rampDirectionFlag = 0
      else
        pwmduty pPWM, wPWMDutyNow    
      endif
    else ' fade
      wPWMDutyNow = wPWMDutyNow min 10 - 10
      pwmduty pPWM, wPWMDutyNow
      if wPWMDutyNow = 0 then: rampDirectionFlag = 1: endif
    endif
  endif
  return
This is the b5a.js javascript file on the pi:
Code:
document.body.innerHTML = "" +
'<html><head><title> LED Control</title></head>' +
'<body><form name = input method = get>' +
' <font color=blue><font size=5>Picaxe Web Server</font><br><br>' +
'  <font color=black>' +
'  <table border="1">' +
'  <tr><td><input type="radio" id="A" name="L" value="1">LED ON</td>' +
'  <td><input type="radio" id="B1" name="L" value="0">LED OFF</td></tr>' +
'  <tr><td><input type="radio" id="C" name="P" value="1">PWM ON </td>' +
'  <td><input type="radio" id="D" name="P" value="0">PWM OFF</td></tr>' +
'  <tr><td><input type="radio" id="E" name="R" value="1">Ramp/Fade ON  </td>' +
'  <td><input type="radio" id="F" name="R" value="0">Ramp/Fade ' +
'    OFF</td></tr></table>' +
'' +
'  <p>PWM Duty Cycle:</p>' +
'  <input type="text" id="G" name="N"><br><br>' +
'' +
'  <p>Select LED:</p>' +
'  <input type="radio" id="R" name="X" value="R">Red<br>' +
'  <input type="radio" id="Y" name="X" value="Y">Yellow<br>' +
'  <input type="radio" id="B" name="X" value="B">Blue<br>' +
'  <input type="radio" id="G" name="X" value="G">Green<br>' +
'  <input type="radio" id="W" name="X" value="W">White<br>' +
'  <input type="radio" id="O" name="X" value="O">Orange<br>' +
'' +
'  <br><button type=submit>Submit</button>' +
'</form></body></html>        '
var ledStatus = arrayCurVals[0];  // this will be "0"
var pwmStatus = arrayCurVals[1]; //this will be "1"
var pwmRamp = arrayCurVals[2]; //this will be "1"
var pwmDuty = arrayCurVals[3]; //this will be, e.g., "321"
var ledColor = arrayCurVals[4]; // this will be "W"

if (ledStatus == 1) { document.getElementById("A").setAttribute("checked", true); }
else { document.getElementById("B1").setAttribute("checked", true); }
if (pwmStatus == 1) { document.getElementById("C").setAttribute("checked", true); }
else { document.getElementById("D").setAttribute("checked", true); }
if (pwmRamp == 1) { document.getElementById("E").setAttribute("checked", true); }
else { document.getElementById("F").setAttribute("checked", true); }
document.getElementById("G").value=pwmDuty
document.getElementById(ledColor).setAttribute("checked", true);
And the s.css file on the pi. All this does at present is set the background (which could be done without CSS), but could be used to sculpt the appearance of the output.
Code:
body {
    background-color: #d0d0d0;
}

h1 {
    color: #fff;
    font-family: Arial, Helvetica, sans-serif;
}
I made perhaps the world's worst tech youtube video, since I was trying to watch the camera and watch my phone to see where to press the buttons,, but at least it shows that the web page works on a phone, and it shows the ramping and fading of the PWMed light:
Attached are the include files, Esp8266.basinc and Server.basinc. Remove ".txt" from the attached files to get the file names you need.
 

Attachments

Last edited:

Electronics Learner 123

Well-known member
Thank you very much,

I highly appreciate this, I have 2 questions:

Can this be run on a picaxe 20x2

Please could you share schematics- I am a big noob but just want to make sure I get it right?
 

lbenson

Senior Member
Can this be run on a picaxe 20x2
With very careful tweaking it might be possible, but the big problem is that the amount of data a browser sends can easily overrun the small scratchpad memory on the 20x2. 28x2 or 40x2 make a far better choice.

Please could you share schematics- I am a big noob but just want to make sure I get it right?
I'll look at doing that. There is actually little to it--the ESP-01 has 3v3 & 0V, Rx and Tx from hserout and hserin, and ch_pd pulled high with 4k7.

I do have Eaglecad schematic and board files. I hooked the ESP-01 to the header marked TCPIP, and added the 2 aqua-colored links to provide a direct connection from the HSER pins to Rx & Tx.
28esp.jpg
Bare PCB: 28htmlGeo.jpg
 
Last edited:

lbenson

Senior Member
Can this be run on a picaxe 20x2
Turns out the tweak needed to run the web server on a 20X2 was not that difficult. The 20X2 has only a 128-byte scratchpad buffer, and some browser responses were overrunning it. Fortunately, nothing after 128 bytes is significant for this application (as far as my experience goes), so I added a setintflags interrupt on hserflag, and if the processor was a 20X2 and the hserptr was greater than 119, I set it back to 119, which results in the excess being effectively discarded.

Here's the crucial code:
Code:
interrupt: ' prevent scratchpad wrap on 20X2
  hserflag = 0
  if hserptr > topOfScratch then: hserptr = topOfScratch: endif
  setintflags %00100000,%00100000 ' interrupt on background hardware serial receive LB
  Return
Here's the layout in Pebble:
20x2_esp_pebble2.jpg
And the working breadboard:
20x2_esp_breadboard.jpg
Slightly modified javascript file, b20.js, hosted on pi:
Code:
document.body.innerHTML = "" +
'<html><head><title> LED Control</title></head>' +
'<body><form name = input method = get>' +
' <font color=blue><font size=5>Picaxe Web Server 20x2</font><br><br>' +
'  <font color=black>' +
'  <table border="1">' +
'  <tr><td><input type="radio" id="A" name="L" value="1">LED ON</td>' +
'  <td><input type="radio" id="B1" name="L" value="0">LED OFF</td></tr>' +
'  <tr><td><input type="radio" id="C1" name="P" value="1">PWM ON </td>' +
'  <td><input type="radio" id="D" name="P" value="0">PWM OFF</td></tr>' +
'  <tr><td><input type="radio" id="E" name="R" value="1">Ramp/Fade ON  </td>' +
'  <td><input type="radio" id="F" name="R" value="0">Ramp/Fade ' +
'    OFF</td></tr></table>' +
'' +
'  <p>PWM Duty Cycle:</p>' +
'  <input type="text" id="G1" name="N"><br><br>' +
'' +
'  <p>Select LED:</p>' +
'  <input type="radio" id="R" name="X" value="R">Red<br>' +
'  <input type="radio" id="G" name="X" value="G">Green<br>' +
'  <input type="radio" id="B" name="X" value="B">Blue<br>' +
'  <input type="radio" id="Y" name="X" value="Y">Yellow<br>' +
'  <input type="radio" id="P" name="X" value="P">Pink<br>' +
'  <input type="radio" id="C" name="X" value="C">Chartruese<br>' +
'  <input type="radio" id="O" name="X" value="O">Orange<br>' +
'' +
'  <br><button type=submit>Submit</button>' +
'</form></body></html>        '
var ledStatus = arrayCurVals[0];  // this will be "0"
var pwmStatus = arrayCurVals[1]; //this will be "1"
var pwmRamp = arrayCurVals[2]; //this will be "1"
var pwmDuty = arrayCurVals[3]; //this will be, e.g., "321"
var ledColor = arrayCurVals[4]; // this will be "W"

if (ledStatus == 1) { document.getElementById("A").setAttribute("checked", true); }
else { document.getElementById("B1").setAttribute("checked", true); }
if (pwmStatus == 1) { document.getElementById("C1").setAttribute("checked", true); }
else { document.getElementById("D").setAttribute("checked", true); }
if (pwmRamp == 1) { document.getElementById("E").setAttribute("checked", true); }
else { document.getElementById("F").setAttribute("checked", true); }
document.getElementById("G1").value=pwmDuty
document.getElementById(ledColor).setAttribute("checked", true);
The user-supplied application-specific code:
Code:
' 20Esp8266
'===== Contents =====

'  InternetControlledPicaxe.bas
'  esp8266.basinc
'  Station.basinc
'  Server.basinc

'===== InternetControlledPicaxe.bas =====

#Picaxe 20X2
#No_Data
#No_Table

; This program connects as a station to a 
; specific access point and then delivers
; HTML pages to anyone who request them.

#terminal 19200
#com 4

#define testAPP1

; This program connects as a station to a 
; specific access point and then delivers
; HTML pages to anyone who request them.

symbol cQuote=34 ' double quote
symbol ledFlag=bit16
symbol pwmFlag=bit17
symbol fadeFlag=bit18
symbol rampDirectionFlag=bit19 ' 0 is down, 1 is up
' variables through w9 (b19:b18) used
symbol wPWMDuty=w10 ' b21:b20
symbol wPWMDutyNow=w11 ' b23:b22
symbol whichLED=b24 ' LED Pin # -- B1-B7
symbol i=b25
symbol chLED=b26 ' LED character value "P","R","Y","B","G","W","C","O"
       ' Pink, Red, Yellow, Blue, Green, White, Chartruese, Orange

; Define access point to connect to

'#Define SSID     "MySSID"
'#Define PASSWORD "MyPW"

; Define an ADC input channel if required

'#Define ADC_CHANNEL 0

; Define a LED output pin if required

'#Define LED_OUTPIN outpinB.7
'#Define LED_DIRPIN    dirB.7

#Define RAMStart 56
#IFDEF testAPP1
  bptr=RAMStart
  for b0=B.0 to B.7: @bptrinc = b0: next b0 ' leds to be turned on
  #ifdef _20X2
    bptr=RAMStart+5: @bptrinc=C.7: @bptrinc=C.4: @bptrinc=C.3
  #ENDIF
  bptr=RAMStart
  high @bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
  pause 1000
  bptr=RAMStart
  low @bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
  pause 1000
  bptr=RAMStart
  for b0=0 to 7: high @bptr: pause 500: low @bptr: inc bptr next b0: pause 500 
  pause 1000
  bptr=RAMStart
  low @bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
  wPWMDuty=0: wPWMDutyNow=0: pwmFlag=0: fadeFlag=0: ledFlag=1: whichLED=2: chLED="B"
  bptr=RAMStart
  if ledFlag = 1 then: high @bptr: else: low @bptr: endif
  if whichLED > 0 then: high whichLED: endif
#ENDIF

#Include "esp2866.basinc"

' #Include "Station.basinc"
#Include "Server.basinc"

putHTML:
  length= 300 ' 234 ' 437 ' 228 ' LB 200303

  ; Indicate we have a reply 

  Gosub SendReply_SendLength

  ; Send the actual reply
  ; Whether the <html><body>...</body></html>
  ; wrapping is required depends on the browser 
  ; which receives the data.
  ; Plain text can be returned which may be
  ; most appropriate if another PICAXE is to
  ; receive the data

  SerTxd( CR, LF, "Send reply - ", #length, " bytes", CR, LF )
  HSerOut 0, ( "<html><head><link type=text/css rel=stylesheet href=http://192.168.1.144:20780/s.css>" )
  pause 50
  HSerOut 0, ( "<link rel='icon' type='image/png' href='data:image/png;base64,iVBORw0KGgo='> " )
  pause 50
  HSerOut 0, ( "</head><body></body>" )
  pause 50

  HSerOut 0, ( "<script>var arrayCurVals = [" )  ' [1,1,0,133,",cQuote,"W",cQuote,"]
  pause 50
  HSerOut 0, ( #ledFlag,",",#pwmFlag,",",#fadeFlag,",",#wPwmDuty,",",cQuote,chLED,cQuote )
  pause 50
  HSerOut 0, ( "];</script>" ) ' 87 is "W"
  pause 50

#ifDef _20X2
  HSerOut 0, ( "<script src=http://192.168.1.144:20780/b20.js></script></html>               " )
#else
  HSerOut 0, ( "<script src=http://192.168.1.144:20780/b28.js></script></html>               " )
#endif
  pause 50
  return

processURL:
  SerTxd( CR, LF, "processURL", CR,LF )
  If Found("favicon.ico") Then
    SerTxd( CR, LF, "Got favicon.ico request", CR,LF )
    uptoPtr = savePtr
    Gosub CloseReply
    Return
  End If

  ptr=saveUrlPtr ' lb
  for i=1 to 24: sertxd(@ptrinc): next i: ptr=saveURLPtr: sertxd(cr,lf)
'#rem
  Do
    select @ptr  ' looking for "A"-"Z" 
                 ' e.g., L=1&P=1&R=1&N=512&X=G LED, PWM, Ramp/Fade, PWM DUTY, LED on B.1-5, B.7
      case "L": ptr=ptr+2 
        if @ptr="1" then : high B.0: ledFlag=1 : else : low B.0: ledFlag=0 : endif ' indicator LED
      case "R": ptr=ptr+2: if @ptr="1" then : fadeFlag=1 : else : fadeFlag=0 : endif ' ramp & fade PWM LED
      case "P": ptr=ptr+2: if @ptr="1" then : pwmFlag=1 : else : pwmFlag=0 : endif ' pwm LED on or off
      case "N": ptr=ptr+2: wPWMDuty=0
        do while @ptr <> "&" and @ptr <> " " 
          if @ptr => "0" and @ptr <= "9" then : wPWMDuty = wPWMDuty * 10 + @ptr - "0" : endif
          inc ptr
        loop
      case "X": ptr=ptr+2
         #ifDef _20x2
           lookdown @ptr,("R","G","B","Y","P","C","O"),whichLED ' B.0-B.4, C.7, C.4
         #else
           lookdown @ptr,(0,"R","Y","B","G","W","C","O"),whichLED ' B.1-B.7
         #endif
'        if whichLED = 6 then : inc whichLED : endif ' 20X2 B.6 becomes B.7
        bptr=RAMStart: low @bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
        bptr=RAMStart+whichLED: high @bptr
        chLED=@ptr
        sertxd("Pin B.",#whichLED," HIGH",cr,lf)
    endselect
    ptr = ptr + 1
  Loop Until ptr => uptoPtr
  if pwmFlag = 1 then
    sertxd("Pwm turning on; duty=",#wPWMDuty," on pin ",#pPWM,cr,lf)
    if fadeFlag = 0 then ' turn on LED, max PWM
      pwmout pwmdiv16, pPWM, 249, wPWMDuty ' 500=50%, 1000=100% ' 1kHz    else
    else
      wPWMDutyNow=wPWMDuty
      pwmout pwmdiv16, pPWM, 249, wPWMDutyNow ' 500=50%, 1000=100% ' 1kHz    else
    endif
  else
    PWMOUT pPWM, OFF
  endif
'#endrem

  return

mainUserLoop: ' this is called every 10ms while idling
  if pwmFlag = 1 and fadeFlag = 1 then
    if rampDirectionFlag = 1 then ' ramp up
      wPWMDutyNow = wPWMDutyNow + 10
      if wPWMDutyNow > wPWMDuty then ' reverse direction
        wPWMDutyNow = wPWMDutyNow min 10 - 10
        rampDirectionFlag = 0
      else
        pwmduty pPWM, wPWMDutyNow    
      endif
    else ' fade
      wPWMDutyNow = wPWMDutyNow min 10 - 10
      pwmduty pPWM, wPWMDutyNow
      if wPWMDutyNow = 0 then: rampDirectionFlag = 1: endif
    endif
  endif
  return
Include files attached. Remove "2.txt" to get the basinc files. I think these will run on the 28X2 and 40X2 if #PICAXE is changed, but haven't tested yet.

The program uses 2992 of 4096 bytes.
 

Attachments

Last edited:

Electronics Learner 123

Well-known member
Turns out the tweak needed to run the web server on a 20X2 was not that difficult. The 20X2 has only a 128-byte scratchpad buffer, and some browser responses were overrunning it. Fortunately, nothing after 128 bytes is significant for this application (as far as my experience goes), so I added a setintflags interrupt on hserflag, and if the processor was a 20X2 and the hserptr was greater than 119, I set it back to 119, which results in the excess being effectively discarded.

Here's the crucial code:
Code:
interrupt: ' prevent scratchpad wrap on 20X2
  hserflag = 0
  if hserptr > topOfScratch then: hserptr = topOfScratch: endif
  setintflags %00100000,%00100000 ' interrupt on background hardware serial receive LB
  Return
Here's the layout in Pebble:
View attachment 23682
And the working breadboard:
View attachment 23679
Slightly modified javascript file, b20.js, hosted on pi:
Code:
document.body.innerHTML = "" +
'<html><head><title> LED Control</title></head>' +
'<body><form name = input method = get>' +
' <font color=blue><font size=5>Picaxe Web Server 20x2</font><br><br>' +
'  <font color=black>' +
'  <table border="1">' +
'  <tr><td><input type="radio" id="A" name="L" value="1">LED ON</td>' +
'  <td><input type="radio" id="B1" name="L" value="0">LED OFF</td></tr>' +
'  <tr><td><input type="radio" id="C1" name="P" value="1">PWM ON </td>' +
'  <td><input type="radio" id="D" name="P" value="0">PWM OFF</td></tr>' +
'  <tr><td><input type="radio" id="E" name="R" value="1">Ramp/Fade ON  </td>' +
'  <td><input type="radio" id="F" name="R" value="0">Ramp/Fade ' +
'    OFF</td></tr></table>' +
'' +
'  <p>PWM Duty Cycle:</p>' +
'  <input type="text" id="G1" name="N"><br><br>' +
'' +
'  <p>Select LED:</p>' +
'  <input type="radio" id="R" name="X" value="R">Red<br>' +
'  <input type="radio" id="G" name="X" value="G">Green<br>' +
'  <input type="radio" id="B" name="X" value="B">Blue<br>' +
'  <input type="radio" id="Y" name="X" value="Y">Yellow<br>' +
'  <input type="radio" id="P" name="X" value="P">Pink<br>' +
'  <input type="radio" id="C" name="X" value="C">Chartruese<br>' +
'  <input type="radio" id="O" name="X" value="O">Orange<br>' +
'' +
'  <br><button type=submit>Submit</button>' +
'</form></body></html>        '
var ledStatus = arrayCurVals[0];  // this will be "0"
var pwmStatus = arrayCurVals[1]; //this will be "1"
var pwmRamp = arrayCurVals[2]; //this will be "1"
var pwmDuty = arrayCurVals[3]; //this will be, e.g., "321"
var ledColor = arrayCurVals[4]; // this will be "W"

if (ledStatus == 1) { document.getElementById("A").setAttribute("checked", true); }
else { document.getElementById("B1").setAttribute("checked", true); }
if (pwmStatus == 1) { document.getElementById("C1").setAttribute("checked", true); }
else { document.getElementById("D").setAttribute("checked", true); }
if (pwmRamp == 1) { document.getElementById("E").setAttribute("checked", true); }
else { document.getElementById("F").setAttribute("checked", true); }
document.getElementById("G1").value=pwmDuty
document.getElementById(ledColor).setAttribute("checked", true);
The user-supplied application-specific code:
Code:
' 20Esp8266
'===== Contents =====

'  InternetControlledPicaxe.bas
'  esp8266.basinc
'  Station.basinc
'  Server.basinc

'===== InternetControlledPicaxe.bas =====

#Picaxe 20X2
#No_Data
#No_Table

; This program connects as a station to a 
; specific access point and then delivers
; HTML pages to anyone who request them.

#terminal 19200
#com 4

#define testAPP1

; This program connects as a station to a 
; specific access point and then delivers
; HTML pages to anyone who request them.

symbol cQuote=34 ' double quote
symbol ledFlag=bit16
symbol pwmFlag=bit17
symbol fadeFlag=bit18
symbol rampDirectionFlag=bit19 ' 0 is down, 1 is up
' variables through w9 (b19:b18) used
symbol wPWMDuty=w10 ' b21:b20
symbol wPWMDutyNow=w11 ' b23:b22
symbol whichLED=b24 ' LED Pin # -- B1-B7
symbol i=b25
symbol chLED=b26 ' LED character value "P","R","Y","B","G","W","C","O"
       ' Pink, Red, Yellow, Blue, Green, White, Chartruese, Orange

; Define access point to connect to

'#Define SSID     "MySSID"
'#Define PASSWORD "MyPW"

; Define an ADC input channel if required

'#Define ADC_CHANNEL 0

; Define a LED output pin if required

'#Define LED_OUTPIN outpinB.7
'#Define LED_DIRPIN    dirB.7

#Define RAMStart 56
#IFDEF testAPP1
  bptr=RAMStart
  for b0=B.0 to B.7: @bptrinc = b0: next b0 ' leds to be turned on
  #ifdef _20X2
    bptr=RAMStart+5: @bptrinc=C.7: @bptrinc=C.4: @bptrinc=C.3
  #ENDIF
  bptr=RAMStart
  high @bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
  pause 1000
  bptr=RAMStart
  low @bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
  pause 1000
  bptr=RAMStart
  for b0=0 to 7: high @bptr: pause 500: low @bptr: inc bptr next b0: pause 500 
  pause 1000
  bptr=RAMStart
  low @bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
  wPWMDuty=0: wPWMDutyNow=0: pwmFlag=0: fadeFlag=0: ledFlag=1: whichLED=2: chLED="B"
  bptr=RAMStart
  if ledFlag = 1 then: high @bptr: else: low @bptr: endif
  if whichLED > 0 then: high whichLED: endif
#ENDIF

#Include "esp2866.basinc"

' #Include "Station.basinc"
#Include "Server.basinc"

putHTML:
  length= 300 ' 234 ' 437 ' 228 ' LB 200303

  ; Indicate we have a reply 

  Gosub SendReply_SendLength

  ; Send the actual reply
  ; Whether the <html><body>...</body></html>
  ; wrapping is required depends on the browser 
  ; which receives the data.
  ; Plain text can be returned which may be
  ; most appropriate if another PICAXE is to
  ; receive the data

  SerTxd( CR, LF, "Send reply - ", #length, " bytes", CR, LF )
  HSerOut 0, ( "<html><head><link type=text/css rel=stylesheet href=http://192.168.1.144:20780/s.css>" )
  pause 50
  HSerOut 0, ( "<link rel='icon' type='image/png' href='data:image/png;base64,iVBORw0KGgo='> " )
  pause 50
  HSerOut 0, ( "</head><body></body>" )
  pause 50

  HSerOut 0, ( "<script>var arrayCurVals = [" )  ' [1,1,0,133,",cQuote,"W",cQuote,"]
  pause 50
  HSerOut 0, ( #ledFlag,",",#pwmFlag,",",#fadeFlag,",",#wPwmDuty,",",cQuote,chLED,cQuote )
  pause 50
  HSerOut 0, ( "];</script>" ) ' 87 is "W"
  pause 50

#ifDef _20X2
  HSerOut 0, ( "<script src=http://192.168.1.144:20780/b20.js></script></html>               " )
#else
  HSerOut 0, ( "<script src=http://192.168.1.144:20780/b28.js></script></html>               " )
#endif
  pause 50
  return

processURL:
  SerTxd( CR, LF, "processURL", CR,LF )
  If Found("favicon.ico") Then
    SerTxd( CR, LF, "Got favicon.ico request", CR,LF )
    uptoPtr = savePtr
    Gosub CloseReply
    Return
  End If

  ptr=saveUrlPtr ' lb
  for i=1 to 24: sertxd(@ptrinc): next i: ptr=saveURLPtr: sertxd(cr,lf)
'#rem
  Do
    select @ptr  ' looking for "A"-"Z" 
                 ' e.g., L=1&P=1&R=1&N=512&X=G LED, PWM, Ramp/Fade, PWM DUTY, LED on B.1-5, B.7
      case "L": ptr=ptr+2 
        if @ptr="1" then : high B.0: ledFlag=1 : else : low B.0: ledFlag=0 : endif ' indicator LED
      case "R": ptr=ptr+2: if @ptr="1" then : fadeFlag=1 : else : fadeFlag=0 : endif ' ramp & fade PWM LED
      case "P": ptr=ptr+2: if @ptr="1" then : pwmFlag=1 : else : pwmFlag=0 : endif ' pwm LED on or off
      case "N": ptr=ptr+2: wPWMDuty=0
        do while @ptr <> "&" and @ptr <> " " 
          if @ptr => "0" and @ptr <= "9" then : wPWMDuty = wPWMDuty * 10 + @ptr - "0" : endif
          inc ptr
        loop
      case "X": ptr=ptr+2
         #ifDef _20x2
           lookdown @ptr,("R","G","B","Y","P","C","O"),whichLED ' B.0-B.4, C.7, C.4
         #else
           lookdown @ptr,(0,"R","Y","B","G","W","C","O"),whichLED ' B.1-B.7
         #endif
'        if whichLED = 6 then : inc whichLED : endif ' 20X2 B.6 becomes B.7
        bptr=RAMStart: low @bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
        bptr=RAMStart+whichLED: high @bptr
        chLED=@ptr
        sertxd("Pin B.",#whichLED," HIGH",cr,lf)
    endselect
    ptr = ptr + 1
  Loop Until ptr => uptoPtr
  if pwmFlag = 1 then
    sertxd("Pwm turning on; duty=",#wPWMDuty," on pin ",#pPWM,cr,lf)
    if fadeFlag = 0 then ' turn on LED, max PWM
      pwmout pwmdiv16, pPWM, 249, wPWMDuty ' 500=50%, 1000=100% ' 1kHz    else
    else
      wPWMDutyNow=wPWMDuty
      pwmout pwmdiv16, pPWM, 249, wPWMDutyNow ' 500=50%, 1000=100% ' 1kHz    else
    endif
  else
    PWMOUT pPWM, OFF
  endif
'#endrem

  return

mainUserLoop: ' this is called every 10ms while idling
  if pwmFlag = 1 and fadeFlag = 1 then
    if rampDirectionFlag = 1 then ' ramp up
      wPWMDutyNow = wPWMDutyNow + 10
      if wPWMDutyNow > wPWMDuty then ' reverse direction
        wPWMDutyNow = wPWMDutyNow min 10 - 10
        rampDirectionFlag = 0
      else
        pwmduty pPWM, wPWMDutyNow    
      endif
    else ' fade
      wPWMDutyNow = wPWMDutyNow min 10 - 10
      pwmduty pPWM, wPWMDutyNow
      if wPWMDutyNow = 0 then: rampDirectionFlag = 1: endif
    endif
  endif
  return
Include files attached. Remove "2.txt" to get the basinc files. I think these will run on the 28X2 and 40X2 if #PICAXE is changed, but haven't tested yet.

The program uses 2992 of 4096 bytes.
Hi Ibenson

I am trying to read the circuit diagram that u have sent for the 20x2 ,however, I am a big noob, is there any chance that you could sent something like an frizzing diagram with the whole microcontroller/ esp in place so that I can understand the circuit?

Kind Regards
Electronics Learner 123
 

lbenson

Senior Member
I haven't used fritzing. I plan to make up, and will publish the schematic for a PCB, but it may be a while.

The 20sip single-inline-pin (SIP) board which I plugged into the breadboard is shown in post 8 in this thread, with eagle cad files included:
 

lbenson

Senior Member
I sent an Eaglecad PCB design off to Oshpark today--$12.45 U.S. for 3 boards, free shipping to Canada.
20ESP-01 Eaglecad.jpg
Eaglecad SCH and BRD files attached--Remove the ".txt" to be able to use the files in Eaglecad.

I've also attached the zip file of the gerbers. This can be sent directly to a pcb fab house like JLCPCB. Cost would probably be around $8 U.S. for 5 boards.

I just sent them off, so untested (except on breadboard, and with at least similar PCB designs for the picaxe part.

JP5 and JP6 together make up the ESP01 footprint--I didn't have an Eaglecad part for that.
 

Attachments

Top