ESP8266 - STM32 serial communication

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: RoccoMarco, lbednarz, utzig, tfAteba, barthess

Dolence
Posts: 7
Joined: Tue Feb 02, 2016 6:53 pm

ESP8266 - STM32 serial communication

Postby Dolence » Wed May 24, 2017 5:49 pm

Hi!

I have some experience with Atmel AVR family and decided it's time to learn a RTOS. It's my first experience with both, ARM and ChibiOS.
I'm trying to write a library to exchange data between a STM32 and an ESP8266 module using ChibiOS Serial Driver. I started the project and while it does work I'm not sure I'm doing things in the proper way.

What I have done so far:
- Serial communication between STM32 and ESP8266 working;
- Serial communication between STM32 and PC working (debug purposes);
- Thread for sending messages to wifi module. I'm using messages to send data to this thread, I'm not sure it's the best solution or if it's implemented as it should be but it's working fine;
- Thread for receiving data from wifi module, actually it's just dumping this data on debug port.

How should I pass received data from wifi module to the function that is sending an AT command? When sending synchronous messages I'm using a pointer to a thread. How to proced when a thread have to send a message to a function?

Here is my code so far:

Code: Select all

/*
 * esp8266.c
 *
 *  Created on: 22/05/2017
 *      Author: Dolence
 */
#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include "esp8266.h"

#define READ_TIMEOUT 1000  // uart read timeout on 1000 ticks
#define WRITE_TIMEOUT 1000 // uart write timeout on 1000 ticks

static BaseSequentialStream * espStream = NULL;
static BaseSequentialStream * dbgStream = NULL;


binary_semaphore_t uart_bsem;
static thread_t *tWifiRx;
static thread_t *tWifiTx;


static const SerialConfig esp8266cfg = {
    115200, //9600, // baud rate
    0,
    0,
    0,
};

static const SerialConfig debugcfg = {
    115200, //9600, // baud rate
    0,
    0,
    0,
};

static THD_WORKING_AREA(waWifiRx, 128);
static THD_FUNCTION(WifiRx, arg) {

  (void)arg;

  event_listener_t elWifidata;

  eventflags_t flags;
  chEvtRegisterMask((event_source_t *)chnGetEventSource((SerialDriver *) espStream), &elWifidata, EVENT_MASK(1));

  while (true) {
    chEvtWaitOneTimeout(EVENT_MASK(1), MS2ST(10));

    chSysLock();
    flags = chEvtGetAndClearFlags(&elWifidata);
    chSysUnlock();

    if (flags & CHN_INPUT_AVAILABLE) {
      msg_t charbuf;
      do {
        charbuf = chnGetTimeout((SerialDriver *) espStream, TIME_IMMEDIATE);
            if (charbuf != Q_TIMEOUT) {
              chSequentialStreamPut(dbgStream, charbuf);
            }
      }
      while (charbuf != Q_TIMEOUT);
    }
  }
  //return 0;
}


static THD_WORKING_AREA(waWifiTx, 128);
static THD_FUNCTION(WifiTx, arg) {

  (void)arg;

  while (true) {
    thread_t *tp = chMsgWait();

    msg_t msg = chMsgGet(tp);

    chprintf(espStream, "%s", msg);

    chMsgRelease(tp, MSG_OK);
  }
}


int esp8266Init(SerialDriver * espDriver, SerialDriver * dbgDriver, int mode)
{
  espStream = (BaseSequentialStream *) espDriver;
  dbgStream = (BaseSequentialStream *) dbgDriver;

  sdStart((SerialDriver *) espStream, &debugcfg);
  sdStart((SerialDriver *) dbgStream, &esp8266cfg);

  //cria o thread de recebimento
  tWifiRx = chThdCreateStatic(waWifiRx, sizeof(waWifiRx), NORMALPRIO, WifiRx, NULL);
  tWifiTx = chThdCreateStatic(waWifiTx, sizeof(waWifiTx), NORMALPRIO, WifiTx, NULL);

  esp8266Cmd("AT+RST\r\n", "teste", 1000);

  return 0;
}


bool esp8266Cmd(const char * cmd, const char * rsp, int cmddelay)
{
  char buffer[200];
  chsnprintf(buffer, sizeof(buffer), "%s", cmd);

  chMsgSend(tWifiTx, (msg_t)buffer);
  if (cmddelay > 0) chThdSleepMilliseconds(cmddelay);

  //return esp8266ReadUntil(rsp, READ_TIMEOUT);
  return 0;
}


bool esp8266ReadUntil(const char * resp, int timeout)
{
  //to be implemented
  thread_t *tp = chMsgWait();

  //do while response doesn't arrive or timeout occurs
  msg_t msg = chMsgGet(tp);
  //
  // ...
  //
  chMsgRelease(tp, MSG_OK);
}



And a pastebin for better readability: https://pastebin.com/G5VBU4ya

Any help, suggestions, tips would be much appreciated. Thanks!

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: ESP8266 - STM32 serial communication

Postby Giovanni » Wed May 24, 2017 5:56 pm

Hi,

I don't understand what you mean for "thread sending a message to a function".

There are only threads, you always send messages to a thread.

Giovanni

Dolence
Posts: 7
Joined: Tue Feb 02, 2016 6:53 pm

Re: ESP8266 - STM32 serial communication

Postby Dolence » Wed May 24, 2017 7:16 pm

WifiTx and WifiRx are threads, I can send a message from inside the function esp8266Cmd() to WifiTx thread using his pointer like this chMsgSend(tWifiTx, (msg_t)buffer);

After I send an AT command I need to wait for a reply message from wifi module. It will be implemented in esp8266ReadUntil(rsp, READ_TIMEOUT)
I don't know how to do this. How could the thread send a message to esp8266ReadUntil? What would be the thread pointer in this case? I think I misunderstood something. What would be the proper way to achieve what I'm trying to do?

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: ESP8266 - STM32 serial communication

Postby Giovanni » Wed May 24, 2017 8:51 pm

Hi,

Don't try to do things too complex, you just need to send a text line and then receive a text line, right? if so the obvious way is to send the line using write() then get one char at time until a EOL is received, you may also insert receive timeouts for robustness, you don't need 2 threads for that.

Giovanni

Dolence
Posts: 7
Joined: Tue Feb 02, 2016 6:53 pm

Re: ESP8266 - STM32 serial communication

Postby Dolence » Wed May 24, 2017 9:07 pm

Giovanni, thanks for replying.

If I use sdWrite to send and sdGet to receive, I wouldn't even need a thread using event flags for receiving data, is it right? All of this become irrelevant...

Code: Select all

static THD_WORKING_AREA(waWifiRx, 128);
static THD_FUNCTION(WifiRx, arg) {

  (void)arg;

  event_listener_t elWifidata;

  eventflags_t flags;
  chEvtRegisterMask((event_source_t *)chnGetEventSource((SerialDriver *) espStream), &elWifidata, EVENT_MASK(1));

  while (true) {
    chEvtWaitOneTimeout(EVENT_MASK(1), MS2ST(10));

    chSysLock();
    flags = chEvtGetAndClearFlags(&elWifidata);
    chSysUnlock();

    if (flags & CHN_INPUT_AVAILABLE) {
      msg_t charbuf;
      do {
        charbuf = chnGetTimeout((SerialDriver *) espStream, TIME_IMMEDIATE);
            if (charbuf != Q_TIMEOUT) {
              chSequentialStreamPut(dbgStream, charbuf);
            }
      }
      while (charbuf != Q_TIMEOUT);
    }
  }
  //return 0;
}


static THD_WORKING_AREA(waWifiTx, 128);
static THD_FUNCTION(WifiTx, arg) {

  (void)arg;

  while (true) {
    thread_t *tp = chMsgWait();

    msg_t msg = chMsgGet(tp);

    chprintf(espStream, "%s", msg);

    chMsgRelease(tp, MSG_OK);
  }
}

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: ESP8266 - STM32 serial communication

Postby Giovanni » Thu May 25, 2017 7:55 am

Up to you, there are many ways to implement this, I suggest to Keep It Simple :)

Threading is not required for this IMHO, just because the system allows threading does not mean that you must or should use them.

Giovanni

Dolence
Posts: 7
Joined: Tue Feb 02, 2016 6:53 pm

Re: ESP8266 - STM32 serial communication

Postby Dolence » Thu May 25, 2017 2:35 pm

Hi Giovanni, thank you again!

It would be nice to learn more about threads and RTOS, it would be good for future usage.
But I do confess that I don't have any idea on how to proceed. I have the thread receiving everything on Rx line, all the time. Then I have this tfunction sending a command and calling another function that wait for a response from module or timeout. How to pass what is being received on the thread right on this moment to this waiting function?
Just another question. There is any plans to release a printed book or even a PDF version of the documentation for on demand printing?

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: ESP8266 - STM32 serial communication

Postby Giovanni » Thu May 25, 2017 3:00 pm

Hi,

If you need a more complex protocol then I suggest to implement a state machine driver by serial driver events, in each state you perform get/put according to the protocol, timeouts would be handled as state machine transitions.

About PDFs, manuals are already available in PDF format on the web site: http://chibios.org/dokuwiki/doku.php?id ... tion:start

The book is web-only for now: http://chibios.org/dokuwiki/doku.php?id ... book:start

Giovanni


Return to “General Support”

Who is online

Users browsing this forum: Baidu [Spider] and 43 guests