ESP8266 + RaspberryPI

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Heute ist mein ESP8266 ESP-01 gekommen und habe mich gleich daran gemacht das Teil zu testen. Vorab der Hinweiß auf folgenden Thread mit genaueren Informationen:

    -> ESP8266 - heisser Tipp für WLAN über rs232


    Mein Ziel ist es einen zusätzlichen USB-WLAN-Stick am PI einzusparen.


    Als Versorgungsspannung verträgt das ESP8266 Module mind. 1,7V und max. 3,6V aber die I/O Ports vertragen maximal 3V3! (Quelle)

    Problem im Bezug auf den alten RaspberryPI A & B ist allerdings dass dieser nicht mehr allzuviele Stromreserven hat, da er selbst ja 700-800mA benötigt und wegen der 1A Polyfuse nur noch ca. 200-300mA (eher weniger als mehr) zur Verfügung steht.. Laut diversen Information u.a. von dreamshader kann es aber vor kommen dass das ESP8266 bis zu 250mA oder sogar 300mA benötigen könnte. Inwiefern das tatsächlich zu einem Problem wird muss ich noch herausfinden.

    Die Pinbelegung des ESP-01 sieht wie folgt aus:

    An den PI habe ich es wie folgt angeschlossen:

    Code
    ESP8266          Raspberry Pi B
    --------------|--------------
    VCC and CH_PD   3V3 (pin# 1)
    GND	         Ground (pin# 6)
    UTXD            GPIO 15 (pin# 10)
    URXD            GPIO 14 (pin# 8)


    Es ist darauf zu achten das TxD vom ESP-01 auf RxD vom PI geht, ebenso wie TxD vom PI auf RxD vom ESP-01. Also verdreht.

    Ausserdem hat es sich als nützlich herausgestellt einen weiteren GPIO vom RaspberryPI mit dem RESET pin des ESP-01 zu verbinden, so brauch man den dann nur auf HIGH setzen um das Modul neu zu starten. Welchen ihr dafür am PI verwendet spielt aber keine Rolle.

    Ob ihr nur einen 3V3 pin vom PI verwendet oder 2 wie auf dem Bild zu sehen spielt keine Rolle, habe das nur aus Übersichtsgründen so gemacht ;)
    Auch habe ich in fritzing auf ein Breadboard (Steckbrett) aus Übersichtsgründen verzichtet, da das Module leider nicht Breadboard-freundlich gebaut wurde und nicht so einfach auf die Mitte des Breadboards gesteckt werden kann... Siehe dazu auch > hier <. Aber ich benutze sowieso Female-Female Kabel und brauch daher kein Breadboard.


    Erst nach Anschluss den PI einschalten.
    Wenn ihr das Modul erst einschaltet nachdem ihr minicom geöffnet habt, kommen viele komische Zeichen - aber wichtig ist das am Ende ein ready ausgegeben wird.

    Bevor man das Modul jetzt ansprechen kann muss erst der UART vom PI freigeschaltet werden. Wie das geht habe ich >> hier << beschrieben. Dieser Schritt ist sehr wichtig! Anschließend den PI neu starten!

    Als nächstes sollte man erst mal minicom verwenden um das Modul zu testen. Zunächst mal installieren:

    Code
    apt-get install minicom

    Alternativ zu minicom kann ich aber auch picocom empfehlen

    Dann starten wir minicom:

    Code
    minicom -b 115200 -o -D /dev/ttyAMA0

    Jetzt geben wir erst mal folgendes ein um sicherzustellen dass die Kommunikation funktioniert:

    Code
    AT+RST

    Damit weisen wir das Modul an einen RESET / Neustart durchzuführen.
    Ausgabe:

    Spoiler anzeigen

    Sollte das nicht der Fall sein stimmt entweder etwas nicht mit der Verkabelung oder der Firmware auf dem Modul.
    Möglicherweise muss man aber auch die Baudrate runter stellen - das kommt auf die jeweilige Firmware an die auf eurem Modul installiert ist. Bei Problemen also noch mal minicom beenden und stattdessen wie folgt aufrufen:

    Code
    minicom -b 9600 -o -D /dev/ttyAMA0

    (Oder eine Baudrate von 57600)

    Eine Liste der verfügbaren AT Befehle findet ihr > hier <

    Jetzt stellen wir eine Verbindung zu unserem WLAN her:

    Code
    AT+CWJAP="SSID","PWD"


    SSID müsst ihr mit eurer SSID ersetzen, also die Kennung eures WLAN's.
    PWD müsst ihr mit eurem WLAN-Password ersetzen.

    Ihr könnt auch die verfügbaren WLAN-Netze scannen:

    Code
    AT+CWLAP

    Unter Umständen muss der Mode vorher noch umgestellt werden:

    Code
    AT+CWMODE=3
    AT+RST

    Um dann zu überprüfen ob ihr erfolgreich Verbindung zu eurem SSID hergestellt habt solltet ihr das noch prüfen, das OK sagt darüber nämlich nichts aus:

    Code
    AT+CWJAP?

    Wenn ihr eine Verbindung hergestellt habt könnt ihr mit folgendem Befehl die IP herausfinden, die dem ESP8622 zugewiesen wurde:

    Code
    AT+CIFSR


    Hier ein Python Script zum testen:

    &quot;Test_ESP8266.py&quot;

    Hab das original etwas modifiziert :fies:

    Das Script stellt erst über euer WLAN eine Verbindung nach Google her und anschließend habt ihr die Möglichkeit eigene AT Befehle an das Modul zu senden, was mit Eingabe von q beendet werden kann.


    Das war jetzt auch schon der Leichte Teil des ganzen. Nun kommt der Schwierige Teil :P Die Einbindung als vollwertige WLAN-Schnittstelle.

    Hier hab ich nun selber noch dran zu knabbern :s

    ..stay tune..


    Um die Firmware zu ändern muss man sich den SDK installieren. Dazu macht ihr am besten folgende Schritte:

    Spoiler anzeigen

    Quelle1 , Quelle2

    Video Tutorial zum compilieren über die VM:

    Externer Inhalt www.youtube.com
    Inhalte von externen Seiten werden ohne deine Zustimmung nicht automatisch geladen und angezeigt.
    Durch die Aktivierung der externen Inhalte erklärst du dich damit einverstanden, dass personenbezogene Daten an Drittplattformen übermittelt werden. Mehr Informationen dazu haben wir in unserer Datenschutzerklärung zur Verfügung gestellt.

  • Hi,


    ...
    Unter Umständen muss der Mode vorher noch umgestellt werden:

    Code
    AT+CWMODE=3


    ...


    vielleicht sollte man noch anmerken, dass bei einer Umstellung des Modus lt. diverser Hinweise ein restart des Moduls (AT+RST) erforderlich ist.

    //EDIT: ach ja ... wichtig ist, dass immer wirklich die gesamte Rückmeldung des Moduls ausgelesen wird. Verbleiben noch Reste der Antwort quasi auf der Leitung, dann bekommt man beim nächsten Absetzen eines Kommandos die Fehlermeldung "busy" ...
    Ausserdem ist es sinnvoll, einen AP-join durch Absetzen eines "AT+CWJAP?" zu überprüfen. Ein voriger check auf ein Ok reicht da nicht aus ...

    cheers,
    -ds-

  • Zum flashen des ESP8266 habe ich ein Arduino Nano v3 genommen da ich das mit dem PI nicht hinkriege..

    Da der Nano mit 5V arbeitet, der ESP-01 aber nur 3V3 verkraftet, muss man hier noch einen Logic Level Converter (Levelshifter) zwischen TX/RX dazwischen schalten. Dazu habe ich diesen verwendet.

    Ihr braucht den Arduino nicht neu flashen! Er muss also nicht zum ISP gemacht werden!
    Der Trick ist am Arduino den RST Pin mit GND zu verbinden, womit der Atmega abgeschaltet wird und der Arduino in einer USB-TTL Konfiguration läuft, also ungestört mit dem FTDI USB-to-TTL Serial chip gesprochen werden kann.

    Hier meine üblichen Bilder um den Anschluss zu verdeutlichen:

    Und hier das ganze Konstrukt:

    Code
    Nano   Level Converter   ESP8266
    -----|-----------------|---------
    5V     HVcc   -> LVcc     VCC
    GND    HV-GND -> LV-GND   GND
    TX     HV-TX  -> LV-TX    TX
    RX     HV-RX  -> LV-RX    RX


    Beim Arduino muss auch noch der RST Pin mit GND verbunden werden, womit der Atmega abgeschaltet wird und der Arduino in einer USB-TTL Konfiguration läuft, also ungestört mit dem FTDI USB-to-TTL Serial chip gesprochen werden kann. Man muss dann den Arduino auch nicht zum ISP machen

    Code
    GND -> RST


    Zusätzlich muss am ESP8266 auch noch 2 Brücken gesetzt werden:

    Code
    GND -> GPIO-0
    VCC -> CH_PD


    Über GPIO-0 wird der ESP in den Flash-Mode gesetzt.

    High Volt = 5V
    Low Volt = 3V3

    Achtet auch unbedingt darauf auf der HV Seite auf jeden Fall 5V drauf zu geben, nicht 3V3! Denn vom Nano kommen 5V über TX und RX die der Converter auch erkennen und Wandeln muss.


    Firmwares und Flash Tools: https://drive.google.com/folderview?id=…g&usp=drive_web
    Am besten ihr flasht euch ESP8266_flasher_V00170901_00_Cloud Update Ready.zip, dann brauch man nie wieder manuell über einen Arduino flashen :cool:

    Zitat

    Finally when the cloud updating mode is done, you don’t have enter into update mode anymore, just run AT commands to updating via online:

    remember to join your router for internet, and run AT+CIUPDATE to get updates.

    Man muss dann aber trotzdem noch GPIO-0 auf GND brücken (also auf LOW ziehen) damit das Device in den Flash-Mode versetzt wird.

    Wenn man das gemacht und eine Verbindung zu seinem WLAN hergestellt hat, sieht das wie folgt aus:


    CIPUPDATE:1 bedeutet -> found server
    CIPUPDATE:1 bedeutet -> connect server
    CIPUPDATE:1 bedeutet -> got edition
    CIPUPDATE:1 bedeutet -> start

    Nach :4 dauert es etwas, wenn das funktioniert hat wird ein OK ausgegeben werden. Kommt aber ein ERROR hat es nicht funktioniert..


    ...stay tune...


    //EDIT:

    Beim Arduino muss auch noch der RST Pin mit GND verbunden werden, womit der Atmega abgeschaltet wird und der Arduino in einer USB-TTL Konfiguration läuft, also ungestört mit dem FTDI USB-to-TTL Serial chip gesprochen werden kann. Man muss dann den Arduino auch nicht zum ISP machen ;)

    Aber was ganz besonders wichtig ist das man TX und RX nicht verdrehen darf! Also 1:1 Arduino-TX auf ESP-TX! Diesen Fehler hab ich selber gemacht grad erst durch Zufall gefunden.


    Was mich jetzt allerdings schon ein bisschen verwirrt ist, dass ich den ESP8266 über den Levelconverter nicht geflasht kriege... Hab ihn jetzt mal stumpf direkt an den Arduino angeschlossen (aber VCC an 3V3) und jetzt lässt er sich problemlos flashen :-/
    Mein Nano gibt über 3V3 leider nur etwas über 3V aus, was aber beim Levelshifter auf der anderen Seite auch ankommt... Naja egal, hauptsache es geht :lol:


    Quellen:

    http://www.ernstc.dk/arduino/esp8266.html
    http://www.rei-labs.net/esp8266-update…e-the-baudrate/
    http://www.rei-labs.net/esp8266-update…e-the-baudrate/
    http://rayshobby.net/?p=9734
    http://www.element14.com/community/grou…pload-to-xively
    http://mcuoneclipse.com/2014/10/15/che…the-frdm-board/
    http://nerdclub-uk.blogspot.de/2014/10/gettin…le-to-work.html
    http://blog.electrodragon.com/cloud-updating…7c-esp8266-now/
    http://importhack.wordpress.com/2014/11/22/how…sor-web-client/

  • Ich hab noch ein Python Script geschrieben (angelehnt ans Test_ESP8266.py aus dem 1.Beitrag), was das ESP Module dazu bringt einen TCP Server zu erzeugen und alles was dort hin geschickt wird, ausgibt. Das ist gerade fürs Debuggen recht hilfreich :angel:

    Voreingestellt ist Port 80.

    Ihr müsst beim ausführen die SSID mit Password als Parameter mit angeben, also zu Beispiel:

    Code
    ./server_ESP8266.py SSID PWD


    Dann wird versucht eine Verbindung herzustelle und die zugewiesene IP ermittelt - was oftmals ein bisschen dauert, also ihr kriegt meistens bei den ersten Zwei Versuchen einen ERROR aber das Script versucht bis zu 10x die IP zu ermitteln was i.d.R. auch reicht.

    Dann wird über AT+CIPMUX=1 eingestellt das 'multiple connections' erlaubt sind.
    Danach wird ein TCP Server eingestellt und enabled: AT+CIPSERVER=1,80 (1=enabled, 80=port)

    Wenn ihr nun einen Browser öffnet und eine Verbindung auf die IP des ESP8266 Modules herstellt, seht ihr auf der Konsole was übergeben wird.

    Genauso könnt ihr aber auch mit zB dem Java Programm SocketText eine Clientverbindung herstellen und irgendeinen Text abschicken welcher dann auch in der Konsole angezeigt wird :)

    Server Script:

    &quot;server_ESP8266.py&quot;

    Beispiel Ausgabe:

    Spoiler anzeigen

    Problem bei diesem Weg ist aber natürlich dass die while Schleife volle CPU Last erzeugt, aber es soll ja auch erst mal nur zum Testen genutzt werden...

  • Mir ist es gelungen das server_ESP8266.py Script auf einfache Weise entscheidend zu optimieren :geek:

    Alt:
    [code=php]
    while not finished: # Dump whatever comes over the TCP link.
    while( ser.inWaiting() :(
    sys.stdout.write( ser.read() )
    sys.stdout.flush()
    [/php]

    Neu:
    [code=php]
    while not finished: # Dump whatever comes over the TCP link.
    data = ser.read(1) # read one, blocking
    n = ser.inWaiting() # look if there is more
    if n:
    data = data + ser.read(n) # and get as much as possible
    if data:
    sys.stdout.write(data)
    sys.stdout.flush()
    [/php]

    Mit dieser kleinen Anpassung wird die CPU solange nichts empfangen nicht mehr (überhaupt nicht mehr null,nix) belastet und sobald Daten empfangen werden steigt die CPU Auslastung nur für kurze Zeit auf ~1%

    :angel:

    &quot;server_ESP8266.py&quot;

    [code=php]#!/usr/bin/python
    # -*- coding: utf-8 -*-
    #

    import sys, serial
    from time import *
    import datetime, string
    #import codecs

    #-------------------------------------------------------------------
    SerialPort = "/dev/ttyAMA0"
    SerialBaudrate = 115200
    servPort = 80
    #-------------------------------------------------------------------
    #initialization and open the port.
    #possible timeout values:
    # 1. None: wait forever, block call
    # 2. 0: non-blocking mode, return immediately
    # 3. x, x is bigger than 0, float allowed, timeout block call
    ser = serial.Serial()
    ser.port = SerialPort
    ser.baudrate = SerialBaudrate
    ser.bytesize = serial.EIGHTBITS #number of bits per bytes
    ser.parity = serial.PARITY_NONE #set parity check: no parity
    ser.stopbits = serial.STOPBITS_ONE #number of stop bits
    #ser.timeout = 1 #non-block read
    ser.timeout = 2.5 #timeout block call
    ser.xonxoff = False #disable software flow control
    ser.rtscts = False #disable hardware (RTS/CTS) flow control
    ser.dsrdtr = False #disable hardware (DSR/DTR) flow control
    ser.writeTimeout = 2 #timeout for write
    #-------------------------------------------------------------------

    if len(sys.argv) != 3:
    print "Usage: server_ESP8266.py SSID Password"
    exit()
    else:
    ssid = sys.argv[1]
    pwd = sys.argv[2]
    print("SSID: %s" % ssid)
    print("PWD: %s" % pwd)

    # ----------------------------------------
    def wifiCommand( sCmd, waitTm=1, sTerm='OK' :(
    lp = 0
    ret = ""
    print(" ")
    print("Cmd: %s" % sCmd)
    ser.flushInput()
    ser.write( sCmd + "\r\n" )
    ret = ser.readline() # Eat echo of command.
    sleep( 0.2 )
    while( lp < waitTm :(
    while( ser.inWaiting() :(
    ret = ser.readline().strip( "\r\n" )
    print(ret)
    lp = 0
    if( ret == sTerm :( break
    if( ret == 'ready' :( break
    if( ret == 'ERROR' :( break
    if( ret == 'Error' :( break
    sleep( 1 )
    lp += 1
    return ret

    # ------------------------------------------
    def wifiCheckRxStream():
    while( ser.inWaiting() :(
    s = ser.readline().strip( "\r\n" )

    # ------------------------------------------
    def main():
    wifiCommand( "AT" ) # Should just return an 'OK'.
    wifiCommand( "AT+CIPCLOSE" ) # Close any open connection.
    wifiCommand( "AT+RST", 5, sTerm='ready' ) # Reset the radio. Returns with a 'ready'.
    wifiCommand( "AT+GMR" ) # Report firmware number.
    wifiCommand( "AT+CWMODE=3" ) # Set mode to 'Sta/ap'.
    #wifiCommand( "AT+CWLAP", 10 ) # Scan for AP nodes. Returns SSID / RSSI.
    # Join Access Point given SSID and Passcode.
    wifiCommand( "AT+CWJAP=\""+ssid+"\",\""+pwd+"\"", 5 )
    wifiCommand( "AT+CWJAP?" )
    # Sometimes it takes a couple querries until we get a IP number.
    sIP = wifiCommand( "AT+CIFSR", 3, sTerm="ERROR" )
    if ( sIP == 'ERROR' :(
    i = 10 # Retry n times.
    while( (sIP == 'ERROR') and (i > 0) :(
    print(i)
    sIP = wifiCommand( "AT+CIFSR", 3, sTerm="ERROR" )
    if( sIP == 'ERROR' :( sleep( 3 )
    i -= 1
    if( i > 0 :(
    print("IP Num: %s"% sIP)
    else:
    print("Bad IP Number.")
    else:
    print("IP Num: %s"% sIP)

    wifiCommand( "AT+CIPMUX=1" )
    cmd = ("AT+CIPSERVER=1,%s"% servPort)
    wifiCommand( cmd ) # Setup ESP Module as Server.

    # while not finished: # Dump whatever comes over the TCP link.
    # while( ser.inWaiting() :(
    # sys.stdout.write( ser.read() )
    # sys.stdout.flush()

    while not finished: # Dump whatever comes over the TCP link.
    data = ser.read(1) # read one, blocking
    n = ser.inWaiting() # look if there is more
    if n:
    data = data + ser.read(n) # and get as much as possible
    if data:
    #sys.stdout.write(codecs.escape_encode(data)[0])
    sys.stdout.write(data)
    sys.stdout.flush()

    # ------------------------------------------
    def _exit():
    global finished
    print("Quit")
    ser.close()
    finished = True
    exit()

    # ------------------------------------------
    if __name__ == '__main__':
    finished = False
    try:
    ser.open()
    except Exception, e:
    print("Error open serial port: " + str(e))
    exit()
    if ser.isOpen():
    try:
    main()
    except Exception, e1:
    finished = True
    print("Error...: " + str(e1))
    except (KeyboardInterrupt, SystemExit):
    _exit()
    else:
    print("Cannot open serial port %s" % SerialPort)
    _exit()
    [/php]

  • Zum flashen des ESP8266 habe ich ein Arduino Nano v3 genommen da ich das mit dem PI nicht hinkriege..


    Hi!

    Danke für deinen Post, er ist sehr hilfreich. Mich würde es sehr interessieren, den ESP direkt über den PI zu flashen,
    weißt Du zufällig mittlerweile, wie das geht?

    besten Gruß,
    F99

  • Bei mir läuft das mit Raspbian Jessie wie folgt:
    1. raspi-config als sudo aufrufen
    2. Unter Punkt "9 Advanced Options" "A8 Serial" auswählen und auf "Nein" setzten
    3. Am besten den RasPi nun runterfahren und ausschalten, dann geht beim folgenden Verbinden nichts schief
    4. RX RasPi mit TX ESP, TX RasPi mit RX ESP, GND mit GND mittels Kabel (Mutti/Mutti) verbinden und erst mal ein loses Kabel auf +3,3V am Raspi stecken.
    5. Raspi wieder hochfahren
    6. Firmware und Pythontool mit dem Raspi runterladen
    7. Am ESP Vcc und CH_PD überbrücken (dauerhaft)
    7. GPIO0 vom ESP mit GND verbinden, erst dann +3,3V vom RasPi mit +Vcc (und CH_PD) verbinden.
    8. Mit

    Code
    sudo python esptool.py --port AMA0  write_flash 0x00000 firmware.bin

    das Flashen beginnen.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!