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):
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.