Problem Web1 Error 1101 on Arduino Webserver

I am very new to both HTML and App Inventor but I feel this is a simple HTML issue that I am just missing the knowledge on. Would be grateful if anyone could assist with this.
I am creating a simple webserver on a MKR1000 that is waiting for a request and then sending a line of data that i plan to parse and display within my app.

The web server works when i connect to it on my phone or pc and open the ip(shown below):
image
But when i open the app on the same devices I get the E1101 error.

The app i am posting here is a extremely simplified version that i am trying to use for just testing this web component, where it should send a request when the button is pressed and display the received text in the text box.

Here is the app:

And its response:

And lastly the part i believe is the problem,

My codebase:


#include <Wire.h>//I2C communitcation library 
#include <math.h>

#define MPU_ADD 0x68          //setting up registers for data from IMU
#define ACCEL_XOUT_H 0x3B
#define GYRO_XOUT_H 0x43
#define PWM_MGMT 0x6B
#define pi 3.1415926535       //PI used for calculations
#include <SPI.h>
#include <WiFi101.h>
#include "arduino_secrets.h" 

//setting up global variables for IMU data and tilt calculations
float accelX, accelY, accelZ, gyroX, gyroY, gyroZ;// variables for raw IMU data
float rollG = 0, pitchG = 0, rollA = 0, pitchA = 0;//var for the actual tilt angles worked out from raw IMU data
float CF_Roll = 0, CF_Pitch = 0; // modified tilt angles based on complimentory filter 
float lastTime = 0, currentTime = 0, TimeDiff = 0;// var used for storing time used for intigration 
float GyroErrorX = 0, GyroErrorY = 0;// var for gyro error used to zero the senor
float AccelErrorX = 0, AccelErrorY = 0;// var for acceleromitor used to zero the sensor

//Global variables for WiFi Server
char ssid[] = SECRET_SSID;        //network SSID (name)
char pass[] = SECRET_PASS;    //network password
int status = WL_IDLE_STATUS;
WiFiServer server(80);
float pitch = 0.0;


void setup() {
  Serial.begin(19200);//starts serial monitor for testing
  while (!Serial) {
    ; // wait for serial port to connect.
  }
  init_IMU();//sets up imu full scale resolution
  Cal_Gyro_Bias();// Runs the gyro caliberation
  Create_AP(); 
}

void loop() {
  dt();// runs function to get time used for calculations
  IMU_Data();// runs function for getting data from imu and runs calculations to determine tilt angles 

  //prints tilt angles to the serial monitor for testing
  Serial.print("Roll: ");
  Serial.println(CF_Roll);
  Serial.print("Pitch: ");
  Serial.println(CF_Pitch);
  delay(50);

  //Check for Connection change to device
  con_Check();
  //Check for a data request via IP
  //If a data request has been made send roll and pitch data via HTML
  req_Handle();
}

void init_IMU(){
  //Start I2C communication
  //set up IMU data output
  Wire.begin();//start I2C commmunication 
  Wire.beginTransmission(MPU_ADD);//talk to IMU over I2C using MPU address 
  Wire.write(PWM_MGMT);// 
  Wire.write(0x00);
  Wire.endTransmission(true);// end I2C communciation 
}

//zeros the IMU gyro
/* doesnt work 

void Cal_Gyro_Bias(){
  float biasX = 0, biasY = 0, biasZ = 0;
  int n = 3000;

  for(int i = 0; i < n; i++){
    Get_Gyro_Data();

    biasX += gyroX;
    biasY += gyroY;
    biasZ += gyroZ;
    delay(2);
  }

  biasX /= n;
  biasY /= n;
  biasZ /= n;

  gyroX -= biasX;
  gyroY -= biasY;
  gyroZ -= biasZ;
}*/

//ignore for now
void Cal_Gyro_Bias(){
  int n = 3000;

  for(int i = 0;i < n;i++){
    Get_Gyro_Data();

    GyroErrorX = GyroErrorX + gyroX;
    GyroErrorY = GyroErrorY + gyroY;
  }

  GyroErrorX = GyroErrorX / n;
  GyroErrorY = GyroErrorY / n;

}

//determine time used for gyro calculations
void dt(){
  currentTime = millis();//millis in built function give current time since MCU power on 
  TimeDiff = (currentTime - lastTime) / 1000.0; //time differnece from last chack divided by 1000 to convert from ms to s
  lastTime = currentTime;
}

//keeps tilt angles bound to 0-360 degrees 
float mapAngles(float angle){
  if(angle > 180){
    angle -= 360.0;
  }

  if(angle < 180){
    angle += 360.0;
  }
  return angle;
}

//request gyro data from IMU 
void Get_Gyro_Data(){
  Wire.beginTransmission(MPU_ADD);//start I2C on the IMU address 
  Wire.write(GYRO_XOUT_H);// set IMU start register location to gyroX data register 
  Wire.endTransmission(true);//end I2C
  Wire.requestFrom(MPU_ADD,6,true);// request 6 btyes from above register 

  //bit shift 8 bits to read high side first then low side
  //divide by scalar value depending on full scale range for sensor 
  gyroX = (Wire.read() << 8 | Wire.read()) / 131.0;//bit shift by one byte to read high side byte frist then low side
  gyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  gyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
}

//request accelerometer data from IMU
void Get_Accel_Data(){
  Wire.beginTransmission(MPU_ADD);//start I2C on the IMU address
  Wire.write(ACCEL_XOUT_H);// set IMU start register location to accelX data register 
  Wire.endTransmission(true);//end I2C
  Wire.requestFrom(MPU_ADD,6,true);// request 6 btyes from above register 

  //bit shift 8 bits to read high side first then low side
  //divide by scalar value depending on full scale range for sensor
  accelX = (Wire.read() << 8 | Wire.read()) / 16384.0;//bit shift by one byte to read high side byte frist then low side
  accelY = (Wire.read() << 8 | Wire.read()) / 16384.0;
  accelZ = (Wire.read() << 8 | Wire.read()) / 16384.0;
}

//intigral for converting gyro data into roll and pitch angles in degrees 
//will prob remove this function can just be done straight in the complemetry filter function
void Gyro_Angles(){
  rollG += gyroX * TimeDiff;//intigrate gyro data to get tilt angle (takes previous roll value and adds gyro data * time past since last calculation)
  pitchG += gyroY * TimeDiff;

}

//trig for converting accelerometer data into roll and pitch angles in degrees
void Accel_Angles(){
  rollA = (atan(accelY / (sqrt((accelX * accelX) + (accelZ * accelZ)))) * 180 / pi);//bunch of trig for acceleromitor titlt angles we can referance the paper for this 
  pitchA = (atan(-1 * accelX / (sqrt((accelY * accelY) + (accelZ * accelZ)))) * 180 / pi);
}

//complementry filter to merge gyro and accelerometer data for increased accuracy and to remove gyro drift
void Complementry_Filter(){
  float a = 0.95;

  CF_Roll = (a * (CF_Roll + gyroX * TimeDiff)) + ((1 - a) * rollA);//adds both the gyro and accel angles with a value to bias which sensor to prioritize
  CF_Pitch = (a * (CF_Pitch + gyroY * TimeDiff)) + ((1 - a) * pitchA);

  CF_Roll = mapAngles(CF_Roll);//converts tilt angle to be within 0 - 360 degrees 
  CF_Pitch = mapAngles(CF_Pitch);
}

//calls all functions for IMU tilt info
void IMU_Data(){
  Get_Gyro_Data();
  Get_Accel_Data();
  Gyro_Angles();
  Accel_Angles();
  Complementry_Filter();
}


///////////////WIFI CODE//////////////
void Create_AP(){
// by default the local IP address of will be 192.168.1.1
  // print the network name (SSID);
  Serial.print("Creating access point named: ");
  Serial.println(ssid);

  // Create open network.
  status = WiFi.beginAP(ssid);
  if (status != WL_AP_LISTENING) {
    Serial.println("Creating access point failed");
    // don't continue
    while (true);
  }
  // wait 10 seconds for connection:
  delay(10000);
  // start the web server on port 80
  server.begin();
  // you're connected now, so print out the status
  printWiFiStatus();

}
void printWiFiStatus() {
  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  // print where to go in a browser:
  Serial.print("To connect to this server go to http://");
  Serial.println(ip);

}
void con_Check(){// compare the previous status to the current status
  if (status != WiFi.status()) {
    //If the connection changes update the variable
    status = WiFi.status();
    
    if (status == WL_AP_CONNECTED) {
      byte remoteMac[6];
      Serial.print("Device connected to AP");
    } else {
      //The device that was connected, disconnected and we are listening for another connection
      Serial.println("Device disconnected from AP");
    }
  }
}
void req_Handle(){
///This is the primary section that will listen for requests and then send data via HTML when it recieves said request 
  WiFiClient client = server.available();   // listen for incoming clients
  if (client) {                             // This Checks if there has been a new data request,
    Serial.println("new request");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out to the serial monitor

                                            //Code above will display the html content that is coming from the request, wait for this to print then send back own html content

        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n"); 
            client.println();
            
            //We will now convert the roll and pitch values into all the variables we need to plot the angle, we do this here so we arent doing constant trig questions until they are required
            //All of this data needs to be converted to strings to allow it to be sent via http.
                                                                                              //All of this can be simplified 
            String XPitch = String(sin(CF_Pitch*DEG_TO_RAD));
            String YPitch = String(cos(CF_Pitch*DEG_TO_RAD));
            String XRoll = String(sin(CF_Roll*DEG_TO_RAD));   //These four values are for plotting the current deviation of the foot from alignment
            String YRoll = String(cos(CF_Roll*DEG_TO_RAD));

            String pitchString = String(CF_Pitch);    //These two values are for calculating and displaying the angle devialtion
            String rollString = String(CF_Roll);

            String time = String(millis()); //This value is to give us the time for the data collection so we can plot it.


            // the content of the HTTP response follows the header:
            
            client.print(XPitch); // Send the updated pitch value
            client.print(",");
            client.print(YPitch); // Send the updated pitch value
            client.print(",");
            client.print(XRoll); // Send the updated pitch value
            client.print(",");
            client.print(YRoll); // Send the updated pitch value
            client.print(",");
            client.print(pitchString); // Send the updated pitch value
            client.print(",");
            client.print(rollString); // Send the updated roll value
            client.print(",");
            client.print(time);                                                      ///Look at pre concatinating this as a array and sending as one for more efficiency
            client.print("");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          }
          else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        }
        else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // The message has been sent, disconnect the request:
    client.stop();
    Serial.println("Message Sent");
  }
}
////////End Of Wifi Modules/////////

Thank you for any assistance, really stuck on this for my group project. I will try to provide any other info required.

Show where in the app you are setting the destination IP address (grabbing at straws)

What happens, if you use a browser on your device together with the ip address as utl?

Taifun

Here is where is set the IP in the web config
image

Remove Data from ResponseFileName (leave blank), and uncheck SaveResponse. You want data, not to save the data to file.

1 Like

What happens, if you use a browser on your device together with the ip address as utl?
Taifun

Sorry not sure I understand what you mean by using the ip address as utl?
I have had the ip open on other devices while trying to use the app to no avail.

I have also tried both opening the ip in browser and using this app on multiple devices. In all cases they can look at the page in browser but the app fails to retrieve data.

Remove Data from ResponseFileName (leave blank), and uncheck SaveResponse. You want data, not to save the data to file.

Thank you TIMAI2.

That has fixed it!
Something so simple as per usual, thank you for the help and quick responses!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.