WiFi... Wo is me.... Problems Problems Problems

idbruceidbruce Posts: 6,164
edited 2020-08-03 - 23:07:57 in Propeller 1
Okay I have a problem :(

Either it is my programming, the Parallax WX ESP8266 WiFi Module, the Propeller Activity Board WX, or a bug in the WiFi programming. I am not sure which it is, but I am unhappy.

Here is the scenario.... I purchased the Parallax WX ESP8266 WiFi Module and the Propeller Activity Board WX specifically for controlling a stepper motor based upon a text file, located on my web server (novelsolutionsonline.com). Last night I finally got around to testing some firmware I had written months ago and to my dismay, the stepper motor was going haywire, skipping steps, stopping, etc... Going into troubleshooting mode, I stripped the code down to the absolute bare minimum. As it stands now, the MAIN function starts a new cog, which puts the stepper driver in an endless loop. First the motor goes in one direction and then it reverses, and then repeats. Even after being all stripped down, the stepper motor still goes crazy. I run similar drivers all the time with no problems. That being said, if I put a lengthy pause after "wifi_connect" the problem subsides, but never completely goes away, and the longer the pause, the better it subsides. And if I pause the main cog completely, the stepper driver and stepper motor work flawlessy.

I am not completely certain, but fairly certain that the WiFi driver should be running in it's own cog, the main should have it's own cog, and the stepper driver driver should have its own cog, so how is any of this affecting my stepper driver, with no external variables? I am baffled :(

I have posted my test code. Hopefully someone can help, otherwise it was a waste of time and money.

EDIT: And before you say it, yes I have tried increasing my stack size tremendously :)
#include "simpletools.h"
#include "wifi.h"
#include "Driver.h"

int main()
{
  int nHandle;
  
  wifi_start(31, 30, 115200, WX_ALL_COM);
  
  pause(1000);
  
  driver_init();
       
  while(1)
  {
    nHandle = wifi_connect("novelsolutionsonline.com", 80);
    
    pause(150000);//  The longer the pause, the longer the problem stays away
    
    wifi_disconnect(nHandle);
    
    pause(3000000);// By halting the main cog, the problem disappears
  }  
}
#include "Driver.h"
#include "simpletools.h"
#include <stdint.h>
#include <stdbool.h>

// cog variables
static int driver_cog = 0;
static int driver_stack[150];

void driver(void *par);

void driver_init()
{
	if(driver_cog == 0)
	{
		driver_cog = 1 + cogstart(&driver, NULL,
			driver_stack, sizeof driver_stack);
	}
}

void driver_stop()
{
	if(driver_cog > 0)
	{
		cogstop(driver_cog - 1);
		driver_cog = 0;
	}
}

void driver(void *par)
{
	int32_t counter;
	uint32_t forward_steps;
	uint32_t reverse_steps;
	uint32_t pause_between_steps;

	// Set DIRA as an output.
	DIRA |= 1 << DIRECTION;

	do
	{
		forward_steps = ONE_DIRECTION_STEPS;
		reverse_steps = ONE_DIRECTION_STEPS;
		pause_between_steps = STEP_PAUSE;

		// Set up the CTRMODE of Counter A for NCO/PWM single-ended.
		CTRA = (4 << 26) | STEP;

		// Set the value to be added to PHSA with every clock cycle.
		FRQA = 1;

		// Set DIRA as an output.
		DIRA |= 1 << STEP;

		// Set the direction of movement
		OUTA |= 1 << DIRECTION;

		// Get the current System Counter value.
		counter = CNT;

		while(forward_steps != 0)
		{
			// Send out a high pulse on the step pin for the desired duration.
			PHSA = -PULSE_WIDTH;

			// Wait for a specified period of time before sending another
			// high pulse to the step pin.
			waitcnt(counter += pause_between_steps);

			// Decrement forward_steps
			forward_steps--;
		}

		// Set the direction of movement
		OUTA &= (~1 << DIRECTION);

		// Get the current System Counter value.
		counter = CNT;

		while(reverse_steps != 0)
		{
			// Send out a high pulse on the step pin for the desired duration.
			PHSA = -PULSE_WIDTH;

			// Wait for a specified period of time before sending another
			// high pulse to the step pin.
			waitcnt(counter += pause_between_steps);

			// Decrement reverse_steps
			reverse_steps--;
		}
	}
	while(driver_cog > 0);
}
#ifndef _DRIVER_H
#define _DRIVER_H

#define PULSE_WIDTH (CLKFREQ / 1000000)
#define STEP_PAUSE (CLKFREQ / 7408)
#define ONE_DIRECTION_STEPS 5556
#define STEP 0
#define DIRECTION 1

void driver_init(void);
void driver_stop(void);

#endif /* _DRIVER_H */

Comments

  • I don't use the WiFi library for my functions so not sure what is happening.

    I replaced your driver code with a simple LED on/off code that I can visually see.

    It seems that pin 0 is being manipulated by the WiFi code causing your issue. I change the driver code STEP pin to 5 and the LED pulses normally.

    Mike
  • idbruce,

    Do you have the latest library files?
    https://www.parallax.com/downloads/propeller-c-learn-folder
  • Yes the Wifi module or code is definitely affecting pin operation in a seperate cog WTF
    Thanks for doing the check, I will alter my stepper pins.
  • Genetix wrote: »
    idbruce,

    Do you have the latest library files?
    https://www.parallax.com/downloads/propeller-c-learn-folder

    the pin0 bug rings a bell, which should be fixed in the latest library.
  • Okay.... Ijust finished altering my overlay board and testing, but I will download the latest library files, just in case mine are not the latest. I guess at this point, I could recheck, after the download.

    Altering the pins did fix all the craziness, however now there is a new problem. After a while, the program does not recognize a change in the settings. I am fairly certain, that this is also a WiFi programming bug or a WiFi hardware glitch, because I never had a problem before when it was hardwired, sending commands over USB.
  • "...to my dismay, the stepper motor was going haywire, skipping steps, stopping, etc..."
    I've had the same experience trying to control DC motors with 433Mhz modules. I did everything I could think of to reduce electrical noise. It improved only slightly. I didn't want to risk destroying my QuickStart board so I used optocouplers to separate my micro from the L298 modules I was using. I used an oscilloscope to verify input and output on the optocouplers...and my motors began to work fine.
    At least during the prototyping stage I will continue to use optocouplers because they are cheaper to replace.
  • I downloaded the latest libraries and reconfigured the board to use pin 0 once again, but that was no fix to the pin 0 problem.
  • I have completely abandoned the WX ESP8266 WiFi Module, because it is not reliable. Too many problems.
  • Sorry to here that. I use these modules on a couple of different projects that access remote websites and get web data in JSON and then parse the data out to display on a panel.

    Web traffic has some issues with latency and failed request that must be accounted for. I also don't use the WiFi library since it wants to use feature I'm not interested in.

    If you tell me what you are trying to do I can probably put together some code that does just what you want and then you can work from there to get a better understanding of how it all works.

    Mike
  • Mike

    This has been a problem from the get go.... When I first started with this endeavor, you helped me out then, and I made progress. Now there is further problems, pin glitches, cogs stop operating, etc...

    I am fairly certain that the WiFi library is a colony of bugs, and I imagine that if I had the time, I would try digging into that library and try to find the bugs that are causing my problems, but I shouldn't have to do that.

    And I imagine that I am going to have similar problems when I start trying to use the blutooth module I purchased.

    Give me a chance to calm down and I may try getting back into it.

  • idbruceidbruce Posts: 6,164
    edited 2020-08-10 - 07:19:12
    WiFi Follow Up:

    I had a bunch of problems getting my WX ESP8266 WiFi Module to do what I wanted it to do, which in my opinion, should have been a simple task, but it wasn't :( .

    If you have read this thread, as well as a couple of other threads I started pertaining to the WX ESP8266 WiFi Module, you will know what some of my problems were. I must admit that I was truly upset about the whole ordeal, but after calming down, I decided to dig in and get it working.

    My goal was actually pretty simple, which was to acquire the value from a text file on an internet server and modify program operation according to this value, but the WiFi library was causing a bunch of havoc with program operation, including IO pin glitches, program stalling, etc.... So instead of starting from scratch, I decided to dig in to the WiFi library and weed it down, just so I could see what was going on.

    Without going into a great amount of detail, I will just supply the necessary information, with the hope that it will help someone with a similar task. However, there are prerequisites to my solution:

    TCP connection
    USB_PGM_TERM

    My solution was to eliminate the use of the WiFi library, and just use portions of modified functions. The WiFi library links to Full Duples Serial (#include "fdserial.h"), so instead of using the WiFi library (#include "wifi.h"), I went straight to the source of all good things "fdserial.h" :) .

    To sum things up quickly.....

    The necessary constants are:
    #define CONNECT 0xE4
    #define CMD 0xFE
    #define SEND 0xEA
    #define RECV 0xE9
    #define CLOSE 0xE8
    #define TCP 0xF5
    #define USB_PGM_TERM -2
    

    The necessary includes are:
    #include "simpletools.h"
    #include "fdserial.h"
    

    The necessary global variables are:
    char wifi_event;
    char wifi_status;
    int wifi_id;
    int wifi_handle;
    
    char *wifi_buf = 0;
    int wifi_buf_size = 64;
    
    fdserial *wifi_fds;
    

    And my modified WiFi functions are:
    fdserial *wifi_start(int wifi_pin_do, int wifi_pin_di, int wifi_baud, int comSelect)
    { 
      wifi_buf = wifi_bufferSize(wifi_buf_size);
    
      wifi_fds = fdserial_open(wifi_pin_do, wifi_pin_di, 0b0100, wifi_baud);
     
      pause(10);
      low(wifi_pin_di);
      pause(1);
      input(wifi_pin_di);
      pause(1);
      
      return wifi_fds;
    }
    
    char *wifi_bufferSize(int bytes)
    {
      if(wifi_buf == 0)
      {
        wifi_buf = malloc(wifi_buf_size);
      }
      else
      {    
        free(wifi_buf);
        wifi_buf = malloc(bytes);
      }
    
      return wifi_buf;   
    }
    
    void wifi_setBuffer(char *buffer, int size)
    {
      if(wifi_buf != 0)
      {    
        free(wifi_buf);
      }    
      wifi_buf = buffer;
      wifi_buf_size = size;
    }
    
    int wifi_connect(char *address, int port)
    {  
      dprint(wifi_fds, "%c%c%s,%d\r", CMD, CONNECT, address, port);
      wifi_replyStringIn(wifi_buf_size - 1);
      sscan(&wifi_buf[2], "%c%d%d", &wifi_event, &wifi_handle, &wifi_id);
    
      int tcpHandle = wifi_handle;
      
      return tcpHandle;
    }
    
    int wifi_print(int protocol, int handle, const char *fmt, ...)
    {
      int n = 0;
      
      memset(wifi_buf, 0, wifi_buf_size);
      
      va_list args;
      va_start(args, fmt);
      n = _dosprnt(fmt, args, wifi_buf);
      va_end(args);
    
      int size = strlen(wifi_buf);
    
      dprint(wifi_fds, "%c%c%d,%d\r", CMD, SEND, handle, size);
    
      for(int n = 0; n < size; n++)
      {
        fdserial_txChar(wifi_fds, wifi_buf[n]);
        if(n > 32)
        {
          waitcnt(CNT + (2 * (CLKFREQ/115200)));
        }      
      } 
    
      wifi_replyStringIn(wifi_buf_size - 1);
    
      return n;
    }
    
    int wifi_scan(int protocol, int handle, const char *fmt, ...)
    {
      int n = 0;
      int size;
      int bytesReady;
      
      size = wifi_buf_size;
      wifi_buf[0] = 0;
      
      if((wifi_event == 'S') || (wifi_event == 'D' ))
      {
        dprint(wifi_fds, "%c%c%d,%d\r", CMD, RECV, handle, size);
        wifi_replyStringIn(wifi_buf_size - 1);
        sscan(&wifi_buf[2], "%c%d", &wifi_event, &bytesReady);
        
        if(bytesReady == 0)
        {
          return 0;
        }
        
        while((n < bytesReady) && (n < size))
        {
          if(fdserial_rxCount(wifi_fds) > 0)
          {
            wifi_buf[n] = fdserial_rxChar(wifi_fds);
            n++;        
          }
        }
      }
    
      va_list args;
      va_start(args, fmt);
      va_end(args);
      
      return n;
    }
    
    int wifi_disconnect(int idOrHandle)
    { 
      dprint(wifi_fds, "%c%c%d\r", CMD, CLOSE, idOrHandle);
      wifi_replyStringIn(wifi_buf_size - 1);
      sscan(&wifi_buf[2], "%c%d", &wifi_event, &wifi_handle);
      
      return wifi_handle;
    }
    
    int wifi_replyStringIn(int maxByteCount)
    {
      int n = 0;
      wifi_buf[n] = 0;
    
      while(1) 
      {
        if(fdserial_rxCount(wifi_fds) > 0)
        {
          wifi_buf[n] = fdserial_rxChar(wifi_fds);
          n++;
          wifi_buf[n] = 0;
    
          if((wifi_buf[n-1] == '\r') || (n == wifi_buf_size - 1) || (n == maxByteCount))
          {
            break;
          }        
        }
      } 
    
      return n;
    }
    

    With these pieces of code, my program now works perfectly, with no stalls or pin glitches on IO pin #0.

    EDIT: Perhaps this code can be weeded down further, but I personally have no need to dig into it that deeply.
  • Bruce,
    Happy to hear you got it working.
    Jim
  • Thanks Jim

    It really was quite an ordeal :) After digging in, if I hadn't fixed it, I probably would have been much more upset :)

    Now I get to see what kind of problems the bluetooth module will give me :) but I am going to take it slowly, because I still have to create a mobile app for it.
  • In your modified WiFi functions, did you happen to extract any more functions. The reason I ask, maybe your WiFi functions could be used with FlexC.

    Since SimpleIDE will not be serviced anymore, I am trying to use FlexC where ever possible. Having a fully functional WiFi lib for FlexC would be a big plus. Having an actual WiFi lib, I think ersmith would have to answer that question. Code size is another factor to be considered when using FlexC, since it does not have CMM.

    Keep up the good work, your contribution is greatly appreciated.

    Ray
  • Ray

    At this point in time, these are the only functions I needed, so they are the only ones that I went through and weeded :) However, I am not sure at the moment what it would entail, but I would like to make it so the Propeller could be programmed using WiFi instead of USB. At which point, the constant USB_PGM_TERM could be changed to WX_ALL_COM. I am certain this task will entail adding more weeded functions :)

    This will have to wait though, until I get my Bluetooth module and app up and running.
  • idBruce... I just want to say thank you. I've been working on something for a couple of days and came to the conclusion last night that the wifi libraries were messed up. My plan was to start debugging them tonight, and literally did one quick forum check first, found your post, copied in the code which you graciously provided, and 10 seconds later... done. Actually, almost done... wifi_print worked out of the gate. I had to add back the simpleterm_suspend and resume calls in wifi_scan to get the result to return properly. Once done, I was truly done (10 min vs the planned 3 hrs). Thank you!
Sign In or Register to comment.