Position problem after motor is home.

AFAIK client.read() gets a single character just like Serial.read() so this cannot work

if (client.read() == "Range1")

I think you need another copy of the function recvWithEndMarker() for receiving the client data

Also note that you must use strcmp() to compare values rather than ==

You would make things much easier for yourself if your web page just sends a single character to identify the button that is pressed.

...R

I have updated my sketch for a single character and replaced "Range1" with "A".

client.println("<a href=\"/A\"\"><button>Range: 1 </button></a>
");
  if (client.available()) {
    if (client.read() == "A")  {
      UserRange = 250;  //User prefered light level Range from Webpage.
      Serial.println("UserRange");
    }
  }

Would i still need recvWithEndMarker()? if so, how can i differentiate from a previous recvWithEndMarker()? When i add this and replace "Serial" with "Client" i see that it will not work.

void recvWithEndMarker() { //=======================================
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void recvWithEndMarker() { //=================================
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  while (Client.available() > 0 && newData == false) {
    rc = Client.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

Thank you again for the help!

Change the function name to recvClientWithEndMarker() and change the buffer name from receivedChars to receivedClientChars

...R

void recvWithEndMarker() { //====== Serial READ ============================
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void recvClientWithEndMarker() { //====== Client Read ========================
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  while (Client.available() > 0 && newData == false) {
    rc = Client.read();

    if (rc != endMarker) {
      receivedClientChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedClientChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

this gives me "expected primary-expression before '.' token" at...

    rc = Client.read();

Thank you again!

As well as what I said in Reply #22 you need to change newData to newClientData. And if you want the client buffer to be a different size from your serial buffer you will need to change numChars to numClientChars

You will need to post the complete program if I am to figure out the error. Also post the actual error message.

...R

Error...

Arduino: 1.8.4 (Mac OS X), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

/Users/name 1/Dropbox/Personal/Arduino/MAD-2/MAD2_Blinds_Project/MAD2_Blinds_Project.ino: In function 'void recvClientWithEndMarker()':
MAD2_Blinds_Project:282: error: expected primary-expression before '.' token
   while (Client.available() > 0 && newClientData == false) {
                ^
MAD2_Blinds_Project:282: error: 'newClientData' was not declared in this scope
   while (Client.available() > 0 && newClientData == false) {
                                    ^
MAD2_Blinds_Project:283: error: expected primary-expression before '.' token
     rc = Client.read();
                ^
MAD2_Blinds_Project:286: error: 'receivedClientChars' was not declared in this scope
       receivedClientChars[ndx] = rc;
       ^
MAD2_Blinds_Project:293: error: 'receivedClientChars' was not declared in this scope
       receivedClientChars[ndx] = '\0'; // terminate the string
       ^
/Users/name 1/Dropbox/Personal/Arduino/MAD-2/MAD2_Blinds_Project/MAD2_Blinds_Project.ino: In function 'void parseClientData()':
MAD2_Blinds_Project:305: error: 'receivedClientChars' was not declared in this scope
   UserRange = atol(receivedClientChars); // note that it is ATOL()
                    ^
/Users/name 1/Dropbox/Personal/Arduino/MAD-2/MAD2_Blinds_Project/MAD2_Blinds_Project.ino: In function 'void showNewClientData()':
MAD2_Blinds_Project:317: error: 'newClientData' was not declared in this scope
   if (newClientData == true) {
       ^
MAD2_Blinds_Project:319: error: 'receivedClientChars' was not declared in this scope
     Serial.println(receivedClientChars);
                    ^
exit status 1
expected primary-expression before '.' token

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

too many characters so the File is attached.

Thank you again.

Blinds_Project.ino (13.6 KB)

Client.available() should be client.available() as in your earlier code.

I suggest you avoid using names that only vary by the case of one character. For example you could have used myClient rather than client (Or 1000 other options :slight_smile: )

I presume you know how to deal with the "was not declared" errors.

...R

Generally i can fix the "was not declared" errors, but i don't see how "client" is not working because it was used in the loop already.

I also did not have to declare anything in "void recvWithEndMarker()" so i'm scratching my head again...

Looking further i see that i have "WiFiClient client = server.available();" inside the main loop so not sure if that helps me. I have tried to move it outside of the loop, but i still get errors.

I will be bald earlier than i had hoped.. lol

Thanks

Current Sketch

Thank you

Blinds_Project.ino (13.2 KB)

AROTTER2:
I also did not have to declare anything in "void recvWithEndMarker()" so i'm scratching my head again...

That's because the relevant global variables are defined at the top of the program.

Now that you have created a new function recvclientWithEndMarker() you will need to define the appropriate global variables for it to use. When your family grows from one child to two children you buy an extra chair and an extra spoon.

If you make those changes and it still throws up errors post the updated code and the error message.

...R

PS. I find recvClientWithEndMarker() much easier to read than recvclientWithEndMarker() YMMV

I added..

int client;
int receivedclientChars;
int newclientData;
int numclientChars;

to the top of sketch if this what you mean, i get new errors. or am i just missing something.

/Users/name 1/Dropbox/Personal/Arduino/x/x_Blinds_Project/x_Blinds_Project.ino: In function 'void recvclientWithEndMarker()':
x_Blinds_Project:290: error: request for member 'available' in 'client', which is of non-class type 'int'
   while (client.available() > 0 && newclientData == false) {
                 ^
x_Blinds_Project:291: error: request for member 'read' in 'client', which is of non-class type 'int'
     rc = client.read();
                 ^
x_Blinds_Project:294: error: invalid types 'int[byte {aka unsigned char}]' for array subscript
       receivedclientChars[ndx] = rc;
                              ^
x_Blinds_Project:301: error: invalid types 'int[byte {aka unsigned char}]' for array subscript
       receivedclientChars[ndx] = '\0'; // terminate the string
                              ^
exit status 1
request for member 'available' in 'client', which is of non-class type 'int'

Thank you again!!!

x_Blinds_Project.ino (13.7 KB)

AROTTER2:
I added..

int client;
int receivedclientChars;
int newclientData;
int numclientChars;

to the top of sketch if this what you mean, i get new errors. or am i just missing something.

This is the scattergun approach to coding. It never works.

You need to define the array receivedclientChars the same way that the array receivedChars is defined.
Likewise for newclientData and numclientChars. Look at this bit

const byte numChars = 32;       //"const" makes the variable Read-Only never to change.
char receivedChars[numChars];   //An array to store the received data.
boolean newData = false;

All you need to do is make a copy of that and change the names

You don't need a variable called client - you already have that on line 168. But I think I see a problem. That variable is defined inside loop() so it can't be seen in other functions.

At the top of your program add

WiFiClient client;

and change line 168 so it is like this

client = server.available();  // listen for incoming clients

...R

yes it was scattergun. the part i was not understanding was the ...

const byte numChars = 32;       //"const" makes the variable Read-Only never to change.
char receivedChars[numChars];   //An array to store the received data.
boolean newData = false;

the remainder i had tried, but received additional errors until now.

This now compiles. I will spend my evening after work studying this.

Thank you again so much! :slight_smile:

This is a little different than we have discussed, but i am now getting the sketch to talk back to the Arduino.

//=== Almost WORKING TEST LOOP ==========================
  if (readString.indexOf('H') > 0)  //checks for H
  {
    digitalWrite(16, HIGH);           //TESTING COMMUNICATION
    Serial.println("Test LED ON");  //TESTING COMMUNICATION
  }
  if (readString.indexOf('I') > 0)   //checks for I
  {
    digitalWrite(16, LOW);            //TESTING COMMUNICATION
    Serial.println("Test LED OFF"); //TESTING COMMUNICATION
  }
  readString = "";                       //Clearing string for next read

This portion of my sketch prints "Test LED ON" when i hit any of the buttons, but prints both "Test LED ON" and Test LED OFF" when i hit my (I) button? It should only print "Test LED ON" with the press of the (H) button.

These will eventually be used to turn on and off manual and auto.

Any thoughts?

Thanks again!!

Blinds_Project.ino (14.2 KB)

AROTTER2:
This is a little different than we have discussed,

And there was me thinking we were making progress :slight_smile:

Sorry, but I don't have the patience to deal with two alternative solutions for the same problem.

And I think you are laying up future problems for your self by using the String class. It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

...R

ok, i will revert back and push forward. :slight_smile:

Thank you again for the guidance!!

As before i am using client and while using a switch i can get "Manual Mode" and "Auto Mode" to print, but i am unable to get the if statement to print "test A" or "test B".

      //---- Web Mode Selection Loop ---------------------------------------------------------------------

      int selection = client.read();
      switch (selection) {

        //=== MANUAL MODE ==================
        case 'Y':
          Serial.println("Manual Mode");
          if (client.read() == 'A')
          {
            Serial.println("test A");
            UserRange = 250;  //User prefered light level Range from Webpage.
            Serial.println(UserRange);
          }
          else if (client.read() == 'B')
          {
            Serial.println("test B");
            UserRange = 1000;  //User prefered light level Range from Webpage.
            Serial.println(UserRange);
          }
          break;

        //=== AUTO MODE ===============================

        case 'Z':
          Serial.println("Auto Mode");
          if (RawToLux(rawValue) < UserRange - 250) {
            Astepper1.move(-10);  // Set the position to move to
            Astepper1.run();  // Start moving the stepper.
          }
          else if (RawToLux(rawValue) > UserRange + 250) {
            Astepper1.move(+10);  // Set the position to move to
            Astepper1.run();  // Start moving the stepper.
          }
          else {
            Astepper1.stop();
          }
          break;
      }

      //---- END of Web Mode Selection loop -----------------------------------------------------------------

    }                         //== end while (client.connected())
    client.stop();            // close the connection:
  }                           //== end if (client)

I am still looking into cstrings.

Thank you again.

Blinds_Project.ino (13.9 KB)

The two functions like this

void parseclientData() { //==============================================================================
  UserRange = atol(receivedclientChars); // note that it is ATOL()
}

should probably be like this

void parseclientData() { //==============================================================================
  if (newclientData == true) {
      UserRange = atol(receivedclientChars); // note that it is ATOL()
  }
}

unable to get the if statement to print "test A" or "test B".

You seem to be trying to do that in this code

    int selection = client.read();
      switch (selection) {

        //=== MANUAL MODE ==================
        case 'Y':
          Serial.println("Manual Mode");
          if (client.read() == 'A')
          {

which is completely the wrong way. All the read()s should be left to the recvclientWithEndMarker() function. By "stealing" characters from the buffer in the way you are doing neither part can work properly.

Think of it this way ... You are the managing director in your top-floor office with the panoramic view. You send one of your junior staff down to the front door to wait for a parcel to arrive. You don't do anything connected with the parcel until the junior staff brings it to you - that's the equivalent of newData being true.

...R

If all the read()s should be left to the recvclientWithEndMarker() function. Should it be written with the receivedclientChars from the recvclientWithEndMarker() function.? it compiles but nothing happens.

      int selection = receivedclientChars; //<<<<was     client.read(); and "Manual Mode" printed
      switch (selection) {
        case 'Y':
          Serial.println("Manual Mode");
          if (receivedclientChars == 'A') //<<<<was     (client.read() == 'A') and nothing happened
          {
            Serial.println("test A");
          }
          else if (receivedclientChars == 'B') //<<<<was     (client.read() == 'B') and nothing happened
          {
            Serial.println("test B");
          }
          break;

Thank you again....

AROTTER2:
If all the read()s should be left to the recvclientWithEndMarker() function. Should it be written with the receivedclientChars from the recvclientWithEndMarker() function.?

Probably. But you have only posted a short snippet of code so I have no idea where the problem might be.

Are you waiting until newclientData == true before trying to access the data?

...R