[Solved] Webserver with ESP8266+Arduino crashes (using SoftwareSerial+interrupt)

Dear all, I have a problem that don't know how to fix and is driving me crazy! This is the story; I have two Arduinos (Nano) connected through SPI. The master is controlling a TFTscreen to control the system, and the slave is conected to some resistor-based sensors and to an ESP-01 as a webserver. The system can be controlled with the TFT or by the internet. Up to here everything is ok (if I only use the TFT or the Internet)

Now the problem; in the void loop of the slave, first I anlyze if there is any operation to be done requested by the master. If it is not the case, then it checks if there is any client connected to the ESP-01 to provide the HTML data. The problem is that, if the master is asking for meassures, lets say once a second, and then an user get connected to the ESP-01 at the same time, the system crashes.

How I tried to solved? I have a line SDRDY to let the master know that data is ready on the slave, so the first solution I thought was to use that line, so when the slave is checking for any client, this line is HIGH "suggesting" to the master not to send any instruction yet. It doesn't work... Second solution was to implement a variable (OperationOnGoing) that is true if the Master is requesting data from the Slave, so in theory, the slave should not check for any client...nothing. Third try was to use SPI.detachInterrupt when the slave starts checking the ESP-01 and then SPI.attachInterrupt() when it finishes, using a delay before check if a client is connectd trying to avoid a continuous attach/detach... In doesn't work either.

I'm usinf WiFiESP.h library to control the ESP-01. I don't know if is that this library has any kind of interrupt or something like that, but the point is that if the master is requesting data and a client request the connection, all the system crashes.

Is there any superengineer or erudite person who knows what is going on, or even better, tell me how to solve it?? Thankyou very much!

You need to post your program.

...R

Hi Robin,

The code is a little bit messy... I post the slave code. If the master is needed as well just let me know:

This is void setup:

void setup() 
{   
  Wire.begin(); // Start the I2C Bus as Master
  Serial.begin(9600);
  ESP.begin(9600); //Begin com. with ESP8266
  dht.begin();
  
  pinMode(MISO, OUTPUT);
  pinMode(SDRDY, OUTPUT);

  
  SPCR |= _BV(SPE); // turn on SPI in slave mode  
  SPCR |= _BV(SPIE); // turn on interrupts
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  SPI.attachInterrupt(); // get ready for an interrupt
  
  digitalWrite(SDRDY, HIGH); //High to inicate an operation on WiFi ESP8266 
  
  WiFi.init(&ESP); // initialize ESP module
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println(F("WiFi shield not present"));    
    while(true);// don't continue:
  }
  ConnectToSSID ();
  PrintIP();
  
  digitalWrite(SDRDY, LOW); //Low to inicate an operation on WiFi ESP8266
  
  pos = 0;   // buffer empty
  process_it = false;
  Serial.println(F("Start:"));
}

This is void loop:

void loop()
{
  if (process_it)
  {
    Serial.print(F("Received from screen: "));
    Serial.println (code);
    OperationOnGoing = true;
    switch (code)
    {
      case 1: //Switch off Channel A
        SwitchOff(1);
        ChannelReady = 'O';
        digitalWrite(SDRDY, HIGH);
      break;
      case 2: //Switch on Channel A
        SwitchOn(1);
        ChannelReady = 'O';
        digitalWrite(SDRDY, HIGH);
      break;
      case 3: //Switch off Channel B
        SwitchOff(2);
        ChannelReady = 'O';
        digitalWrite(SDRDY, HIGH);
      break;
      case 4: //Switch on Channel B
        SwitchOn(2);
        ChannelReady = 'O';
        digitalWrite(SDRDY, HIGH);
      break;
      case 5: //Read Current Channel A
        pos = 0;
        ReadCurrent(1);
        ChannelReady = 'A';
        digitalWrite(SDRDY, HIGH);
      break;
      case 6: //Read Current Channel B
        pos = 0;
        ReadCurrent(2);
        ChannelReady = 'B';
        digitalWrite(SDRDY, HIGH);
      break;
      case 7: //Read State Channel A
        pos = 0;
        HowIsTheState(1);
        ChannelReady = 'C';
        digitalWrite(SDRDY, HIGH);
      break;
      case 8: //Read State Channel B
        pos = 0;
        HowIsTheState(2);
        ChannelReady = 'D';
        digitalWrite(SDRDY, HIGH);
      break;      
      case 9: //Read Temperature and Humidity        
        pos = 0;
        hum = dht.readHumidity();
        temp = dht.readTemperature(); // Read temperature as Celsius (the default)
        Serial.print(F("Temperature: "));
        Serial.print(temp,DEC);
        Serial.print(F("   Humidity: "));
        Serial.println(hum,DEC);
              
        TempHum[0] = highByte(int(hum));
        TempHum[1] = lowByte(int(hum));
        TempHum[2] = highByte(int(temp));
        TempHum[3] = lowByte(int(temp));
        if (isnan(hum) || isnan(temp) ) // Check if any reads failed and exit early (to try again).
        {
          Serial.println("Failed to read from DHT sensor!");
          return;
        }
        ChannelReady = 'T';
        digitalWrite(SDRDY, HIGH);
        break;
      }     
      pos = 0;
      process_it = false;
  }
 
   
  delay(500);

  if (!OperationOnGoing)
  {
      digitalWrite(SDRDY,HIGH);
      SPI.detachInterrupt();
      WiFiEspClient client = server.available(); // Check if a client has connected 
    if (!client) 
    {       
      SPI.attachInterrupt();
      digitalWrite(SDRDY,LOW);  
      return;
    }
    else
    {       
      boolean currentLineIsBlank = true; // an http request ends with a blank line
      while (client.connected()) 
      {
        if (client.available()) 
        {
          char c = client.read();
          Serial.write(c);
          if (c == '\n' && currentLineIsBlank) 
          {
            Serial.println(F("Sending response"));
            client.print(F(
              "HTTP/1.1 200 OK\r\n"
              "Content-Type: text/html\r\n"
              "Connection: close\r\n"  // the connection will be closed after completion of the response
              "Refresh: 20\r\n"        // refresh the page automatically every 20 sec
              "\r\n"));
            client.print(F("<!DOCTYPE HTML>\r\n"));
            client.print(F("<html>\r\n"));
            client.print(F("Requests received: "));
            client.print(++reqCount);
            client.print(F("
\r\n"));
            client.print(F("Temperature: "));
            client.print(temp);
            client.print(F("    "));
            client.print(F("Humidity: "));
            client.print(hum);
            client.print(F("
\r\n"));
            client.print(F("
\r\n"));
            client.print(F("<font color=\"black\"> <b> CHA: </b> </font>"));
            if(StateA[0]==1)
            {
              client.print(F("<font color=\"green\"> ON  </font>"));
            }
            else
            {
              client.print(F("<font color=\"red\"> OFF </font>"));
            }
              client.print(F("                       "));
              client.print(F("<font color=\"black\"> <b> CHB: </b> </font>"));
            if(StateB[0]==1)
            {
              client.print(F("<font color=\"green\"> ON  </font>"));
            }
            else
            {
              client.print(F("<font color=\"red\"> OFF </font>"));
            }
              client.print(F("
\r\n"));
              client.print(F("</html>\r\n"));
              break;
          }
          if (c == '\n') 
          {           
            currentLineIsBlank = true; // you're starting a new line
          }
          else if (c != '\r') 
          {            
            currentLineIsBlank = false; // you've gotten a character on the current line
          }
        }
      }    
      delay(10); // give the web browser time to receive the data
    
      client.stop(); // close the connection:
      Serial.println(F("Client disconnected"));
    }
     SPI.attachInterrupt();
     digitalWrite(SDRDY,LOW);
  }  
}

and this the ISR

ISR (SPI_STC_vect)
{
  byte c = SPDR;  // grab byte from SPI Data Register
  if (c == 0)
  {
    SPI.transfer(ChannelReady);
    delayMicroseconds(20);
    ChannelReady = ' ';
    pos = 0;
    digitalWrite(SDRDY, LOW);
  }
  else if (c == 'A')
  {
    SPI.transfer(bufferA[pos]);
    delayMicroseconds(20);
    pos++;
    if (pos==5)
    {
      digitalWrite(SDRDY, LOW);
      OperationOnGoing = false;
    }
  }
  else if (c == 'B')
  {
    SPI.transfer(bufferB[pos]);
    delayMicroseconds(20);
    pos++;
    if (pos==5)
    {
      digitalWrite(SDRDY, LOW);
      OperationOnGoing = false;
    }
  }
  else if (c == 'C')
  {
    SPI.transfer(StateA[0]);
    delayMicroseconds(20);

    digitalWrite(SDRDY, LOW);
    OperationOnGoing = false;

  }
  else if (c == 'D')
  {
    SPI.transfer(StateB[0]);
    delayMicroseconds(20);
    
    digitalWrite(SDRDY, LOW);
    OperationOnGoing = false;
    
  }
  else if (c == 'T')
  {
    SPI.transfer(TempHum[pos]);
    delayMicroseconds(20);
    pos++;
    if (pos==4)
    {
      OperationOnGoing = false;
      digitalWrite(SDRDY, LOW);
    }
  }
  else
  {
    code = c;
    process_it = true;
    OperationOnGoing = true;
    digitalWrite(SDRDY, LOW);
  }
}

Don't use the SPI library in slave mode. Using SPI.transfer() inside an interrupt routine is particularly a bad idea because the call waits until the interrupt was called. That may end in nirvana.

Instead of

SPI.transfer(data);

just use

SPDR = data;

Also:

SPI.attachInterrupt(); // get ready for an interrupt

is the same as:

SPCR |= _BV(SPIE); // turn on interrupts
SPI.setClockDivider(SPI_CLOCK_DIV8);

isn't necessary because the clocking is done by the master.

Do you initialize the SS pin (D10) as INPUT?

Next time, please provide the complete code and not just excerpts, some variable definitions may be important. Please also provide a wiring schemata.

bokeauss:
The code is a little bit messy... I post the slave code.

Please post a complete program. As well as the unseen parts being important I am not going to take the risk of making mistakes while joining parts together.

And please post both programs.

...R

Hi again,

here I post the main program in the slave. (I am avoiding parts that I consider are not relevant)

#include <Wire.h> //Comunicacion I2C
#include <SPI.h> //Comunicacion SPI
#include <avr/interrupt.h>
#include <avr/io.h>
#include "pins_arduino.h"


//Libraries for IoT
#include "WiFiEsp.h"

#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
#endif


//IoT variables
SoftwareSerial ESP(3, 2); // RX | TX
char ssid[] = "WiFi_ReaL_Ya";
char pass[] = "mkhzp2tf";
int Status = WL_IDLE_STATUS;
int reqCount = 0; 
WiFiEspServer server(80);

#define SDRDY 5 // slave data ready
#define SS 10
#include "DHT.h"

#define DHTPIN 14    // what digital pin we're connected to
#define DHTTYPE DHT11   // DHT 11

byte t = 0;
byte r = 0;
byte aux = 0;

bool OperationOnGoing = false;

volatile byte pos;
volatile boolean process_it;
volatile boolean send_data;
volatile byte instruccion;

int x = 0;
int Regleta = 10; //Direccion de la regleta
int b = 9;
int dir = Regleta;

char bufferA[10];
char bufferB[10];
char StateA[10];
char StateB[10];

char TempHum[10];

char buffers[10];

boolean StateOfChannel = false;


String palabra;
float number = 0;
int count = 0;
byte code = 0;
String ValueA = "";
String ValueB = "";

float hum = 0;
float temp = 0;

char ChannelReady = ' ';
char TempReady = ' ';
DHT dht(DHTPIN, DHTTYPE);

RingBuffer buf(8);
void setup() 
{   
  Wire.begin(); // Start the I2C Bus as Master
  Serial.begin(9600);
  ESP.begin(9600); //Begin com. with ESP8266
  dht.begin();
  
  pinMode(SS, INPUT);  
  pinMode(MISO, OUTPUT);
  pinMode(SDRDY, OUTPUT);

  
  SPCR |= _BV(SPE); // turn on SPI in slave mode  
  SPCR |= _BV(SPIE); // turn on interrupts
  
  digitalWrite(SDRDY, HIGH); //High to inicate an operation on WiFi ESP8266 
  
  WiFi.init(&ESP); // initialize ESP module
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println(F("WiFi shield not present"));    
    while(true);// don't continue:
  }
  ConnectToSSID ();
  PrintIP();
  
  digitalWrite(SDRDY, LOW); //Low to inicate an operation on WiFi ESP8266
  
  pos = 0;   // buffer empty
  process_it = false;
  Serial.println(F("Start:"));
}




void loop()
{

  if (process_it)
  {
    Serial.print(F("Received from screen: "));
    Serial.println (code);
    OperationOnGoing = true;
    switch (code)
    {
      case 1: //Switch off Channel A
        SwitchOff(1);
        ChannelReady = 'O';
        digitalWrite(SDRDY, HIGH);
      break;
      case 2: //Switch on Channel A
        SwitchOn(1);
        ChannelReady = 'O';
        digitalWrite(SDRDY, HIGH);
      break;
      case 3: //Switch off Channel B
        SwitchOff(2);
        ChannelReady = 'O';
        digitalWrite(SDRDY, HIGH);
      break;
      case 4: //Switch on Channel B
        SwitchOn(2);
        ChannelReady = 'O';
        digitalWrite(SDRDY, HIGH);
      break;
      case 5: //Read Current Channel A
        pos = 0;
        ReadCurrent(1);
        ChannelReady = 'A';
        digitalWrite(SDRDY, HIGH);
      break;
      case 6: //Read Current Channel B
        pos = 0;
        ReadCurrent(2);
        ChannelReady = 'B';
        digitalWrite(SDRDY, HIGH);
      break;
      case 7: //Read State Channel A
        pos = 0;
        HowIsTheState(1);
        ChannelReady = 'C';
        digitalWrite(SDRDY, HIGH);
      break;
      case 8: //Read State Channel B
        pos = 0;
        HowIsTheState(2);
        ChannelReady = 'D';
        digitalWrite(SDRDY, HIGH);
      break;      
      case 9: //Read Temperature and Humidity        
        pos = 0;
        hum = dht.readHumidity();
        temp = dht.readTemperature(); // Read temperature as Celsius (the default)
        Serial.print(F("Temperature: "));
        Serial.print(temp,DEC);
        Serial.print(F("   Humidity: "));
        Serial.println(hum,DEC);
              
        TempHum[0] = highByte(int(hum));
        TempHum[1] = lowByte(int(hum));
        TempHum[2] = highByte(int(temp));
        TempHum[3] = lowByte(int(temp));
        if (isnan(hum) || isnan(temp) ) // Check if any reads failed and exit early (to try again).
        {
          Serial.println("Failed to read from DHT sensor!");
          return;
        }
        ChannelReady = 'T';
        digitalWrite(SDRDY, HIGH);
        break;
      }     
      pos = 0;
      process_it = false;
  }
 
   
  delay(500);

  if (!OperationOnGoing)
  {
  
  digitalWrite(SDRDY,HIGH);
  SPI.detachInterrupt();
 // noInterrupts();
  WiFiEspClient client = server.available();
    if (client) 
    {
      Serial.println("New client");
      buf.init();       
      while (client.connected()) 
      {
        if (client.available()) 
        {
          char c = client.read();
          buf.push(c);
          if (buf.endsWith("\r\n\r\n")) 
          {
            client.print(F(
              "HTTP/1.1 200 OK\r\n"
              "Content-Type: text/html\r\n"
              "Connection: close\r\n"  // the connection will be closed after completion of the response
              "Refresh: 20\r\n"        // refresh the page automatically every 20 sec
              "\r\n"));
            client.print(F("<!DOCTYPE HTML>\r\n"));
            client.print(F("Requests received: "));
            client.print(++reqCount);
            client.print(F("
\r\n"));
            client.print(F("Temperature: "));
            client.print(temp);
            client.print(F("    "));
            client.print(F("Humidity: "));
            client.print(hum);
            client.print(F("
\r\n"));
            client.print(F("
\r\n"));
            client.print(F("<font color=\"black\"> <b> CHA: </b> </font>"));
            if(StateA[0]==1)
            {
              client.print(F("<font color=\"green\"> ON  </font>"));
            }
            else
            {
              client.print(F("<font color=\"red\"> OFF </font>"));
            }
              client.print(F("                       "));
              client.print(F("<font color=\"black\"> <b> CHB: </b> </font>"));
            if(StateB[0]==1)
            {
              client.print(F("<font color=\"green\"> ON  </font>"));
            }
            else
            {
              client.print(F("<font color=\"red\"> OFF </font>"));
            }
              client.print(F("
\r\n"));
              client.print(F("</html>\r\n"));
              break;
          }
          if (buf.endsWith("GET /H")) 
          {           
            //turn LED ON
          }
          else if (buf.endsWith("GET /L")) 
          {            
            //Turn LED OFF
          }
        }
      }    
      delay(10); // give the web browser time to receive the data
    
      client.stop(); // close the connection:
      Serial.println(F("Client disconnected"));
    }
     //interrupts();
     SPI.attachInterrupt();
     digitalWrite(SDRDY,LOW);
  }  
}

ISR (SPI_STC_vect)
{
  byte c = SPDR;  // grab byte from SPI Data Register
  if (c == 0)
  {
    SPI.transfer(ChannelReady);
    delayMicroseconds(20);
    ChannelReady = ' ';
    pos = 0;
    digitalWrite(SDRDY, LOW);
  }
  else if (c == 'A')
  {
    SPI.transfer(bufferA[pos]);
    delayMicroseconds(20);
    pos++;
    if (pos==5)
    {
      digitalWrite(SDRDY, LOW);
      OperationOnGoing = false;
    }
  }
  else if (c == 'B')
  {
    SPI.transfer(bufferB[pos]);
    delayMicroseconds(20);
    pos++;
    if (pos==5)
    {
      digitalWrite(SDRDY, LOW);
      OperationOnGoing = false;
    }
  }
  else if (c == 'C')
  {
    SPI.transfer(StateA[0]);
    delayMicroseconds(20);

    digitalWrite(SDRDY, LOW);
    OperationOnGoing = false;

  }
  else if (c == 'D')
  {
    SPI.transfer(StateB[0]);
    delayMicroseconds(20);
    
    digitalWrite(SDRDY, LOW);
    OperationOnGoing = false;
    
  }
  else if (c == 'T')
  {
    SPI.transfer(TempHum[pos]);
    delayMicroseconds(20);
    pos++;
    if (pos==4)
    {
      OperationOnGoing = false;
      digitalWrite(SDRDY, LOW);
    }
  }
  else
  {
    code = c;
    process_it = true;
    OperationOnGoing = true;
    digitalWrite(SDRDY, LOW);
  }
}

And this is the code on the master

#include <SPI.h>
#include <Adafruit_GFX.h>    // Libreria de graficos
#include <Adafruit_TFTLCD.h> // Libreria de LCD 
#include <TouchScreen.h>     // Libreria del panel tactil

#define SS 10
#define SDRDY A5

char myString[10];
int actualStringCharacter = 0;

bool operating = false;

int LastButtonPressed = 0;
bool Flag = true;
bool Flag_ok = false;

byte button = 0;

byte CHA_State = 0;
byte CHB_State = 0;

TSPoint p;

boolean ObtainedA = false;
boolean ObtainedB = false;
boolean TimeToStart = false;

long initialTime = millis();

TouchScreen ts = TouchScreen(8, A3, A2, 9, 375); 

void setup(void) 
{
  pinMode(13, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  digitalWrite(6,HIGH);
  digitalWrite(7,HIGH);
  pinMode(SS,OUTPUT);
  digitalWrite(SS, HIGH);
  Serial.begin(9600);

//Start SPI communication
  pinMode(SDRDY, INPUT);
  SPI.begin ();
  SPI.setClockDivider(SPI_CLOCK_DIV8);

  tft.begin(0x9341); // Init LCD
  tft.fillScreen(0x0000); // Set screen Black
  tft.setRotation(2); // Set screen position

  while(digitalRead(SDRDY)) {delay(1);}  

  askState(1);
  while(!digitalRead(SDRDY)) {}
  
  if (Read_Demand()=='C') 
  {
    Read_State(1);          
  }
    
  askState(2);
  while(!digitalRead(SDRDY)) {}   
  if (Read_Demand()=='D') 
  {
      Read_State(2);          
  }
   
  Main_Menu();
  mode = 0;
  TimeToStart = true;
  initialTime = millis();
}

byte transferAndWait (const byte what)
{
  byte a = SPI.transfer (what);
  delayMicroseconds (20);
  return a;
} // end of transferAndWait


void loop(void) 
{   
   Read_TouchButtons(); 
   switch (mode)
   {
    case 0:   
      button = Determine_Main_Menu_Touched_Button(X,Y);
      Analyze_Main_Menu_Pressed_Buttons();     
    break;
    
    case 1:      
      button = Determine_Outlet_Menu_Touched_Button(X,Y);
      Analyze_Outlet_Menu_Pressed_Buttons();
      if ((CHA_State == true)&&(Request_FlagA == false)&&(Request_FlagB == false)&&((TimeToStart == true)||(ObtainedB == true)))
      { 
        ReadCurrent(2);
        Operation_Ongoing = true;
        Request_FlagA = true;
        TimeToStart = false;
      }
    
      if ((CHB_State == true)&&(Request_FlagA == false)&&(Request_FlagB == false)&&((TimeToStart == true)||(ObtainedA == true)))
      { 
        Serial.println("Asking for B current"); 
        ReadCurrent(1);
        Operation_Ongoing = true;
        Request_FlagB = true;
        TimeToStart = false;
      }    
      if ((CHA_State == false))
      {
        if ((CHB_State == true))  //solo Canal B conectado
        {           
            ObtainedA = true;
        }
      }
      else
      {
        if ((CHB_State == false))  // Solo canal A conetado
        {        
          ObtainedB = true;
        }
      }          
      if (((Request_FlagA == true)||(Request_FlagB == true))&&(digitalRead(A5)==true))
      {
        if (ReadDataS() == false)
        {
          PrintCurrentA(valor);
        }
        else
        {
          PrintCurrentB(valor);         
        }
        Operation_Ongoing = false;
      }
      
      if ((ObtainedA == true)&&(ObtainedB == true))
      {
          ObtainedA = false;
          ObtainedB = false;
          TimeToStart = true;
      }  
     break;
   }


}

here are the master spi communications subroutines:

void CheckTempAndHum()
{
      if (((millis()-initialTime)>10000)&&(Request_FlagA == false)&&(Request_FlagB == false))
      {
          LastTemp = temperature;
          LastHum = humidity;
          ReadTempHum();
          initialTime = millis();
          if ((LastTemp!= temperature) || (LastHum!=humidity))
          {
            RemoveTempHum(LastTemp,LastHum);
            Paint_Header();
          }
      }
}

void ReadTempHum()
{
      while(digitalRead(SDRDY)) {}
  
      SendInsruction(9);

      while(!digitalRead(SDRDY)) {}
            
      char x = Read_Demand();

      digitalWrite(SS, LOW);   
      delayMicroseconds(20); 

      transferAndWait(x);
      delayMicroseconds(20);
      humidity = transferAndWait(x);
      humidity = humidity << 8;
         
      transferAndWait(x);
      delayMicroseconds(20);
      humidity += transferAndWait(x);

      transferAndWait(x);
      delayMicroseconds(20);
      temperature = transferAndWait(x);
      temperature = temperature << 8;

      transferAndWait(x);
      delayMicroseconds(20);
      temperature += transferAndWait(x);
      digitalWrite(SS,HIGH);
}

I don't understand the relationship between the code in Reply #7 and that in #6 and #5?

In the code in Reply #5 why is your ISR longer than this

ISR (SPI_STC_vect)
{
  byte c = SPDR;  // grab byte from SPI Data Register
  newSPIdata = true;
}

The rest of the stuff does not need to be in the ISR. And, especially, you should not be wasting time in an ISR with a delay.

On each occasion when you receive SPI data do you only expect a single byte - or are you expecting a message with a few bytes? If the latter I would write the program to receive all the bytes before analysing any of them.

Please provide a description of how your program is intended to work - what each part does (or should do).

I hope that is not the real SSID or password.

...R

The code on post #5 is the program on the slave, and the code on #6 and #7 (SPI subroutines on the master) the program of the master.

The system has two current sensors, two relays controlling one outlet each (each one connected to a current sensor) and on temp and Humidity sensor. On the ISR I have a Switch structure because in dependance of the request of the master, the answer is different. For instance, if i want to know if one channel is On or OFF, the answer is only 1 byte, but if I want to read the current, the answer is 4 bytes (4 ASCII characters)

How should be then the transfer of information??

bokeauss:
On the ISR I have a Switch structure because in dependance of the request of the master, the answer is different. For instance, if i want to know if one channel is On or OFF, the answer is only 1 byte, but if I want to read the current, the answer is 4 bytes (4 ASCII characters)

How should be then the transfer of information??

I can see the SWITCH structure but in every case is just seems to read 2 bytes - for example Tb or Db (where b is some byte). I don't see any code to receive 4 bytes.

When I asked, in Reply #8 for a description I was hoping you would provide something far more detailed - a step-by-step walk-through of the program.

Also I cannot place the code in Reply #5 in the context of the problem described in your Original Post.

I think a simple diagram showing the system you are trying to work with would also be a big help.

At the moment you know all about the project and I feel I only know a teeny bit about it - and maybe not the part that leads me to say "Ahhh ...."

Finally, if the code in Replies #6 and #7 are all part of one program please post it as a complete program.

...R

Thanks Robin2 for your time. I think I've identified the problem, and it is not dealing with SPI interrupts but with SoftwareSerial interrupts (I didn't know this library uses interrupts...)

I suspect that the problem is related with SoftwareSerial because if I use noInterrupts() the part of the code corresponding to the Webserver get freeze. I found other thread where it seems that the problem was solved by including in SoftwareSerial library two soubroutines to enable and disable interrupts.

I have included this in SoftwareSerial library:

void SoftwareSerial::enable()
{
     *_pcint_maskreg |= _pcint_maskvalue;
}

void SoftwareSerial::disable()
{
     *_pcint_maskreg &= ~_pcint_maskvalue;
}

I didn't try it yet. As soon as I do I will report if this solved my problem...

bokeauss:
Thanks Robin2 for your time. I think I've identified the problem, .....

Let me repeat, with emphasis what I said in Reply #10

At the moment you know all about the project and I feel I only know a teeny bit about it - and maybe not the part that leads me to say "Ahhh ...."

Now you have wandered off down another pathway making the thing even more confusing for me.

...R

I think I've identified the problem, and it is not dealing with SPI interrupts but with SoftwareSerial interrupts (I didn't know this library uses interrupts...)

SoftwareSerial not only uses interrupts for the reception side it also blocks interrupts during sending of characters. I strongly suggest not using SoftwareSerial in your case. Connect the WiFi chip by hardware serial and your problems probably decrease. If you need a debugging possibility, use the AltSoftSerial library which uses a timer to send out characters and doesn't block interrupts for disastrous long periods as SoftwareSerial does (but is limited in pin choice).

Hi pylon, thankyou very much for your advice! I will try to use AltSoftSerial and once everything is debugged will try to use hardwareSerial.

I will report if the problem was fixed. Thankyou very much

Hi guys:

First, I can confirm that the error is related with interrupts on SoftwareSerial library. I've been testing the solution proposed on reply #11 (stop interrputs on SoftwareSerial) and it works, but still not working really fine....

Now the problem is that if you connect to the IP when the SoftSerial port is "disabled", you loose that request, and when the SoftSerial is enabled it doesn't have have it.

I'm going to try next the solution using AltSoftSerial. Do any of you know if this will happen using this library also??

Thanks in advance

Hi again,

Second test, now using AltSoftSerial.h as it was suggested by pylon work really find. Now I dont need to "stop" serial interruptions, and also it seems that it is possible to send request when the system is doing other task and it is not "lost" as when using the other solution.

Thanks a lot to pylon how gave me the advice!!

Now I need to go deeper on wify connection because sometimes I get the message [wifi] TIMEOUT and don't understand yet why...

but again Thanks pylon!!!!!