Arduino -ketju (kysymykset/keskustelu)

Liittynyt
22.09.2019
Viestejä
141
Mun mielestä tossa ongelmallisessa sketchissa on jotain pykälää kummempaa pakko olla, kun tällä alla olevalla sketchilla wifiin yhdistäminen onnistuu suoraan ja heti:

#include <ESP8266WiFi.h>

void setup()
{
Serial.begin(115200);
Serial.println();

WiFi.begin("network-name", "pass-to-network");

Serial.print("Connecting");
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println();

Serial.print("Connected, IP address: ");
Serial.println(WiFi.localIP());
}

void loop() {}

jos nimenomaan tällä korvaisi tuon ongelmallisen wifi-kohdan kokonaan. En vain ymmärrä kun tuolla on parikin kohtaa missä mainitaan näitä wifiin liittyviä kirjastoja ja niihin liittyviä askareita. Askareista tulee paskareita kun alan lähmimään. :)
Eipä tuossa näyttäisi pikaisella vilkauksella olevan muita vastaavia wifiin yhdistämis askareita. Voit koittaa korvata setupista tuon while loopin vaikka tällä:

C++:
while (WiFi.status() != WL_CONNECTED) {
        if (i > 40) // Try 40 times to connect to Wifi
        {
            Serial.print("Restarting Wifi");
            ESP.reset(); // Reset Wifi stack if more than 40 trys
            WiFi.begin(WLAN_SSID, WLAN_PASS);
        }
        delay(500);
        Serial.print(".");
        ESP.wdtFeed();   
        i++;
    }

Uskaltaisin väittää että ongelma johtuu tuosta jatkuvasta WiFi.begin() kutsumisesta. Tosin jos @ississ kokemukset pitää paikkansa niin joudut vähän enemmän tuota koodia remppaamaan. Helpolla siitäkin selviää (olettaen ettei tuossa muita ihmeitä tule vastaan).
 
Liittynyt
17.01.2018
Viestejä
797
Olihan se pakko testata ;)

Kuten @tomnav valistuneesti arvasi, ongelma tulee siitä että kutsutaan koko ajan WiFi.begin(). Kun sen ottaa pois loopista niin ottaa yhteyden.
Tämä toimii:
Koodi:
void initwifi() {
    ESP.wdtFeed();
    WiFi.setAutoReconnect(true);
    WiFi.mode(WIFI_STA);
    Serial.print("Connecting to ");
    Serial.println(WLAN_SSID);
    WiFi.begin(WLAN_SSID, WLAN_PASS);
    int i = 0;
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        if (i > 40) {
            Serial.print("No wifi connection. Restarting ESP...");
            ESP.reset();
        }
        i++;
        ESP.wdtFeed();
        delay(500);
    }
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    ESP.wdtFeed();
}
Voi ja kannattaa käyttää esim näin:
Koodi:
void setup(void) {
    Serial.println("setup wifi");
    initwifi();
    
    // http setup tässä
}

void loop() {
    if (WiFi.status() != WL_CONNECTED) {
        Serial.println("wifi connection lost! Reconnecting...");
        initwifi();
    }
    
    // Tee tässä tarvittavat hommelit

    // http serverin hommat
    server.handleClient();
}
 
Liittynyt
19.10.2016
Viestejä
783
Ensinnäkin kiitos @ississ ja @tomnav Teille molemmille vastauksista. Tuumasta toimeen kronologisessa vastausjärjestyksessä ja testaamaan. :)
Tein @tomnav ehdottaman while:n korvauksen, jonka lopputuloksena ESP vihdoin yhdisti wifiin. Wau!

Nyt yritän ymmärtää, että mikä ero @ississ kahdella korvausesimerkillä tuohon nyt todistetusti toimivaan on? En saanut tuota ensimmäistä alkuunsakaan toimimaan, upotin sen siis tällä tavalla wifi.begin:n tilalle:

C++:
/*
 *  Contains code from:
 *  http://randomnerdtutorials.com/esp8266-remote-controlled-sockets/
 *  http://www.bruhautomation.com/p/cheapest-wifi-automated-blinds.html
 *  https://www.arduino.cc/en/Tutorial/Sweep
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 */

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Servo.h>

#define WLAN_SSID       "YOUR WIFI SSID" //change to your Wifi SSID
#define WLAN_PASS       "YOUR WIFI PASSWORD" //change to your Wifi Password

MDNSResponder mdns;
ESP8266WebServer server(80);

int servoPin = 0; //Servo on GPIO0 or NODEMCU pin D3
const int buttonPin = 12; //manual button on GPIO12 or NODEMCU pin D6
int buttonState = 0;
int direction = 0;
int setting = 0; //Startup with blinds closed
int position = 90;
Servo servoA;

String webPage = "";

void setup(void) {
  WiFi.mode(WIFI_STA);
  webPage += "<h1>ESP8266 Web Server</h1><p>Blinds<br>";
  webPage += "<a href=\"0\"><button>0</button></a><br>";
  webPage += "<a href=\"10\"><button>10</button></a><br>";
  webPage += "<a href=\"20\"><button>20</button></a><br>";
  webPage += "<a href=\"30\"><button>30</button></a><br>";
  webPage += "<a href=\"40\"><button>40</button></a><br>";
  webPage += "<a href=\"50\"><button>50</button></a><br>";
  webPage += "<a href=\"60\"><button>60</button></a><br>";
  webPage += "<a href=\"70\"><button>70</button></a><br>";
  webPage += "<a href=\"80\"><button>80</button></a><br>";
  webPage += "<a href=\"90\"><button>90</button></a><br>";
  webPage += "<a href=\"100\"><button>100</button></a><br>";

  delay(1000);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  delay(500);
  Serial.println("Blind Startup Sequence");
  delay(500);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);
  WiFi.begin(WLAN_SSID, WLAN_PASS);
  // Set a static IP (optional)
  //IPAddress ip(10,0,1,50);
  //IPAddress gateway(10,0,1,1);
  //IPAddress subnet(255, 255, 255, 0);
  //WiFi.config(ip, gateway, subnet);
  // End of set a static IP (optional)
  delay(500);
  int i = 0;

void initwifi() {
    ESP.wdtFeed();
    WiFi.setAutoReconnect(true);
    WiFi.mode(WIFI_STA);
    Serial.print("Connecting to ");
    Serial.println(WLAN_SSID);
    WiFi.begin(WLAN_SSID, WLAN_PASS);
    int i = 0;
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        if (i > 40) {
            Serial.print("No wifi connection. Restarting ESP...");
            ESP.reset();
        }
        i++;
        ESP.wdtFeed();
        delay(500);
    }
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    ESP.wdtFeed();
}

server.on("/", []() { server.send(200, "text/html", webPage); });
server.on("/100", []() { server.send(200, "text/html", webPage); setting = 180; });
server.on("/99", []() { server.send(200, "text/html", webPage);  setting = 180; });
server.on("/98", []() { server.send(200, "text/html", webPage);  setting = 180; });
server.on("/97", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/96", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/95", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/94", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/93", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/92", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/91", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/90", []() { server.send(200, "text/html", webPage);  setting = 162; });

server.on("/89", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/88", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/87", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/86", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/85", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/84", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/83", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/82", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/81", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/80", []() { server.send(200, "text/html", webPage);  setting = 144; });

server.on("/79", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/78", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/77", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/76", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/75", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/74", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/73", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/72", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/71", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/70", []() { server.send(200, "text/html", webPage);  setting = 126; });

server.on("/69", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/68", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/67", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/66", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/65", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/64", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/63", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/62", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/61", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/60", []() { server.send(200, "text/html", webPage);  setting = 108; });

server.on("/59", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/58", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/57", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/56", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/55", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/54", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/53", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/52", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/51", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/50", []() { server.send(200, "text/html", webPage);  setting = 90; });

server.on("/49", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/48", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/47", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/46", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/45", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/44", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/43", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/42", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/41", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/40", []() { server.send(200, "text/html", webPage);  setting = 72; });


server.on("/39", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/38", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/37", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/36", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/35", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/34", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/33", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/32", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/31", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/30", []() { server.send(200, "text/html", webPage);  setting = 54; });

server.on("/29", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/28", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/27", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/26", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/25", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/24", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/23", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/22", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/21", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/20", []() { server.send(200, "text/html", webPage);  setting = 36; });

server.on("/19", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/18", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/17", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/16", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/15", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/14", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/13", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/12", []() { server.send(200, "text/html", webPage);  setting = 18; });
server.on("/11", []() { server.send(200, "text/html", webPage);  setting = 18; });
server.on("/10", []() { server.send(200, "text/html", webPage);  setting = 18; }); 

server.on("/9", []() { server.send(200, "text/html", webPage);   setting = 18; });
server.on("/8", []() { server.send(200, "text/html", webPage);   setting = 18; });
server.on("/7", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/6", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/5", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/4", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/3", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/2", []() { server.send(200, "text/html", webPage);   setting = 0; });
server.on("/1", []() { server.send(200, "text/html", webPage);   setting = 0; });
server.on("/0", []() { server.send(200, "text/html", webPage);   setting = 0; });
  server.begin();
  Serial.println("HTTP server started");
}


void loop() {
buttonState = digitalRead(buttonPin);

if(buttonState == LOW && setting <= 180 && direction == 0){
  setting++;
  delay(0);
  if(setting == 180){
    direction = 1;
    }
  }
 
if(buttonState == LOW && setting >= 0 && direction == 1){
  setting--;
  delay(0);
  if(setting == 0){
    direction = 0;
    }
  }

if(position < setting){
   servoA.attach(servoPin);
   servoA.write(position++);
   delay(5);
     Serial.print("Setting: "); 
     Serial.println(setting);
     Serial.print("Position: ");
     Serial.println(position);
   }
  
if(position > setting){
   servoA.attach(servoPin);
   servoA.write(position--);
   delay(5);
     Serial.print("Setting: "); 
     Serial.println(setting);
     Serial.print("Position: ");
     Serial.println(position);
   }

if(position == setting){
  servoA.detach();
  }
server.handleClient();
}

Ja tämän lopputuloksena saan errorin:

"a function-definition is not allowed here before '{ token"

Miksei tuohon kohtaan koodia voi lisätä void-lausetta, en ymmärrä. Ja toki jos joku tästä hieman viitsii vinkata niin olisin onnellinen, mutta toimii porttiteorian tavoin ja tämän jälkeen tulen kuormittamaan Teitä tuon @ississ :n toisen esimerkin pohjalta. Sinällään ymmärrän mitä siinä koodin järjestyksestä kerrotaan, mutta saattaa olla, että vaatii hieman lisäkysymyksiä kuten "mikä hitto tuosta koodista on selkeästi http-setuppia ja missä kohtaa siirrytään toiseen. Nimimerkillä: aina yhtä kujalla
 
Liittynyt
17.01.2018
Viestejä
797
Ensinnäkin kiitos @ississ ja @tomnav Teille molemmille vastauksista. Tuumasta toimeen kronologisessa vastausjärjestyksessä ja testaamaan. :)
Tein @tomnav ehdottaman while:n korvauksen, jonka lopputuloksena ESP vihdoin yhdisti wifiin. Wau!

Nyt yritän ymmärtää, että mikä ero @ississ kahdella korvausesimerkillä tuohon nyt todistetusti toimivaan on? En saanut tuota ensimmäistä alkuunsakaan toimimaan, upotin sen siis tällä tavalla wifi.begin:n tilalle:

C++:
/*
*  Contains code from:
*  http://randomnerdtutorials.com/esp8266-remote-controlled-sockets/
*  http://www.bruhautomation.com/p/cheapest-wifi-automated-blinds.html
*  https://www.arduino.cc/en/Tutorial/Sweep
*
*  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License. You may obtain a copy of the License at:
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
*  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
*  for the specific language governing permissions and limitations under the License.
*/

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Servo.h>

#define WLAN_SSID       "YOUR WIFI SSID" //change to your Wifi SSID
#define WLAN_PASS       "YOUR WIFI PASSWORD" //change to your Wifi Password

MDNSResponder mdns;
ESP8266WebServer server(80);

int servoPin = 0; //Servo on GPIO0 or NODEMCU pin D3
const int buttonPin = 12; //manual button on GPIO12 or NODEMCU pin D6
int buttonState = 0;
int direction = 0;
int setting = 0; //Startup with blinds closed
int position = 90;
Servo servoA;

String webPage = "";

void setup(void) {
  WiFi.mode(WIFI_STA);
  webPage += "<h1>ESP8266 Web Server</h1><p>Blinds<br>";
  webPage += "<a href=\"0\"><button>0</button></a><br>";
  webPage += "<a href=\"10\"><button>10</button></a><br>";
  webPage += "<a href=\"20\"><button>20</button></a><br>";
  webPage += "<a href=\"30\"><button>30</button></a><br>";
  webPage += "<a href=\"40\"><button>40</button></a><br>";
  webPage += "<a href=\"50\"><button>50</button></a><br>";
  webPage += "<a href=\"60\"><button>60</button></a><br>";
  webPage += "<a href=\"70\"><button>70</button></a><br>";
  webPage += "<a href=\"80\"><button>80</button></a><br>";
  webPage += "<a href=\"90\"><button>90</button></a><br>";
  webPage += "<a href=\"100\"><button>100</button></a><br>";

  delay(1000);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  delay(500);
  Serial.println("Blind Startup Sequence");
  delay(500);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);
  WiFi.begin(WLAN_SSID, WLAN_PASS);
  // Set a static IP (optional)
  //IPAddress ip(10,0,1,50);
  //IPAddress gateway(10,0,1,1);
  //IPAddress subnet(255, 255, 255, 0);
  //WiFi.config(ip, gateway, subnet);
  // End of set a static IP (optional)
  delay(500);
  int i = 0;

void initwifi() {
    ESP.wdtFeed();
    WiFi.setAutoReconnect(true);
    WiFi.mode(WIFI_STA);
    Serial.print("Connecting to ");
    Serial.println(WLAN_SSID);
    WiFi.begin(WLAN_SSID, WLAN_PASS);
    int i = 0;
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        if (i > 40) {
            Serial.print("No wifi connection. Restarting ESP...");
            ESP.reset();
        }
        i++;
        ESP.wdtFeed();
        delay(500);
    }
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    ESP.wdtFeed();
}

server.on("/", []() { server.send(200, "text/html", webPage); });
server.on("/100", []() { server.send(200, "text/html", webPage); setting = 180; });
server.on("/99", []() { server.send(200, "text/html", webPage);  setting = 180; });
server.on("/98", []() { server.send(200, "text/html", webPage);  setting = 180; });
server.on("/97", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/96", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/95", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/94", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/93", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/92", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/91", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/90", []() { server.send(200, "text/html", webPage);  setting = 162; });

server.on("/89", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/88", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/87", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/86", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/85", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/84", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/83", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/82", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/81", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/80", []() { server.send(200, "text/html", webPage);  setting = 144; });

server.on("/79", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/78", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/77", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/76", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/75", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/74", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/73", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/72", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/71", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/70", []() { server.send(200, "text/html", webPage);  setting = 126; });

server.on("/69", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/68", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/67", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/66", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/65", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/64", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/63", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/62", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/61", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/60", []() { server.send(200, "text/html", webPage);  setting = 108; });

server.on("/59", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/58", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/57", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/56", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/55", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/54", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/53", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/52", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/51", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/50", []() { server.send(200, "text/html", webPage);  setting = 90; });

server.on("/49", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/48", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/47", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/46", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/45", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/44", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/43", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/42", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/41", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/40", []() { server.send(200, "text/html", webPage);  setting = 72; });


server.on("/39", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/38", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/37", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/36", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/35", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/34", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/33", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/32", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/31", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/30", []() { server.send(200, "text/html", webPage);  setting = 54; });

server.on("/29", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/28", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/27", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/26", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/25", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/24", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/23", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/22", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/21", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/20", []() { server.send(200, "text/html", webPage);  setting = 36; });

server.on("/19", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/18", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/17", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/16", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/15", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/14", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/13", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/12", []() { server.send(200, "text/html", webPage);  setting = 18; });
server.on("/11", []() { server.send(200, "text/html", webPage);  setting = 18; });
server.on("/10", []() { server.send(200, "text/html", webPage);  setting = 18; });

server.on("/9", []() { server.send(200, "text/html", webPage);   setting = 18; });
server.on("/8", []() { server.send(200, "text/html", webPage);   setting = 18; });
server.on("/7", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/6", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/5", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/4", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/3", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/2", []() { server.send(200, "text/html", webPage);   setting = 0; });
server.on("/1", []() { server.send(200, "text/html", webPage);   setting = 0; });
server.on("/0", []() { server.send(200, "text/html", webPage);   setting = 0; });
  server.begin();
  Serial.println("HTTP server started");
}


void loop() {
buttonState = digitalRead(buttonPin);

if(buttonState == LOW && setting <= 180 && direction == 0){
  setting++;
  delay(0);
  if(setting == 180){
    direction = 1;
    }
  }

if(buttonState == LOW && setting >= 0 && direction == 1){
  setting--;
  delay(0);
  if(setting == 0){
    direction = 0;
    }
  }

if(position < setting){
   servoA.attach(servoPin);
   servoA.write(position++);
   delay(5);
     Serial.print("Setting: ");
     Serial.println(setting);
     Serial.print("Position: ");
     Serial.println(position);
   }

if(position > setting){
   servoA.attach(servoPin);
   servoA.write(position--);
   delay(5);
     Serial.print("Setting: ");
     Serial.println(setting);
     Serial.print("Position: ");
     Serial.println(position);
   }

if(position == setting){
  servoA.detach();
  }
server.handleClient();
}

Ja tämän lopputuloksena saan errorin:

"a function-definition is not allowed here before '{ token"

Miksei tuohon kohtaan koodia voi lisätä void-lausetta, en ymmärrä.
C/C++ ei voi tehdä funktiota funktion sisälle, siksi tulee virhe.

Tarkoitus on siis tehdä funktio initwifi:

void initwifi() {
// koodi tässä
}

ja sitä käytetään setupissa:

void setup() {
// koodia
initwifi();
// lisää koodia
}

Jos kaiken haluaa setupin sisään niin sen mun esimerkin initwifin sisältö pitää kopioida setup- funktioon mutta sitten sitä ei voi käyttää uudelleen loopissa toteuttamaan uudelleen yhdistämistä.

On siis parempi tehdä oma initwifi()- funktio jota kutsutaan tarpeellisista paikoista.


Ja toki jos joku tästä hieman viitsii vinkata niin olisin onnellinen, mutta toimii porttiteorian tavoin ja tämän jälkeen tulen kuormittamaan Teitä tuon @ississ :n toisen esimerkin pohjalta. Sinällään ymmärrän mitä siinä koodin järjestyksestä kerrotaan, mutta saattaa olla, että vaatii hieman lisäkysymyksiä kuten "mikä hitto tuosta koodista on selkeästi http-setuppia ja missä kohtaa siirrytään toiseen. Nimimerkillä: aina yhtä kujalla
Tästä ensin iltalukemiseksi hyvä perusteos niin tulee käytetty kieli tutuksi. Vaikka Arduino onkin C++ niin pohjalla pitää olla C- osaaminen. The C programming language
Ainakin osuus funktioista ja niiden parametreista.

Niin ja esimerkissäni ei ollut ollenkaan http setuppia, se on wifista erillinen ja toivottavasti mainitsin jo aiemmin että lähde tavallaan tyhjästä ja kopioi/tee pikkuhiljaa lisää toiminnallisuuksia niin saat testattua edelliset ennen uusien tekemistä. Jos tekee kaiken kerralla niin voi olla vaikea löytää ratkaisuja jos ongelmia on monessa paikassa.

Ja koodin pilkkominen pieniin funktioihin auttaa ymmärtämisessä ja uudelleen käytettävyydessä.
 
Liittynyt
17.01.2018
Viestejä
797
Tässä on vielä yksi esimerkki tavasta joka ehkä kannattaa myös opetella.
Tuo esimerkin server.on() jokaiselle asetusarvolle on muuten kiva mutta mitäs sitten jos asetettavia arvoja on enemmän kuin 1 ? Lisäksi se vie yllättävän paljon kooditilaa, kulutus kasvaa 56% => 60% kun lisää ne tutoriaalin 100 riviä tuohon alla olevaan esimerkkiin. Lisäksi esimerkkikoodi hoitaa minkä tahansa numeron antamisen parametrina, ei vain 0-100 jos on tarpeen.

Tämän pitäisi toimia kunhan laittaa oikean SSIDn ja salasanan. Toivottavasti en kämmeltänyt kun lisäsin kommentit jälkikäteen;)

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

#define WLAN_SSID "SSID TÄHÄN"
#define WLAN_PASS "SALASANA TÄHÄN"

ESP8266WebServer server(80);

// Säädettävä arvo
int value = 50;
int prev_value = value;

// Perus- sivu, 10 nappulaa vastaaville arvoille.
// handler tukee GET- pyyntöjä muodossa http://<ip osoite>/?value=<numeroarvo välillä 0...10>
// Otsikon "Blinds" jälkeen on paikka viestille jossa näytetään nykyinen asetettu arvo " Value = <arvo>"
String webPage = "<html><head><title>Blinds</title></head><body>\n \
<h1>ESP8266 Web Server</h1><p>Blinds @@MESSAGE@@<br>\n \
<a href=\"/?value=0\"><button>0</button></a><br>\n \
<a href=\"/?value=10\"><button>10</button></a><br>\n \
<a href=\"/?value=20\"><button>20</button></a><br>\n \
<a href=\"/?value=30\"><button>30</button></a><br>\n \
<a href=\"/?value=40\"><button>40</button></a><br>\n \
<a href=\"/?value=50\"><button>50</button></a><br>\n \
<a href=\"/?value=60\"><button>60</button></a><br>\n \
<a href=\"/?value=70\"><button>70</button></a><br>\n \
<a href=\"/?value=80\"><button>80</button></a><br>\n \
<a href=\"/?value=90\"><button>90</button></a><br>\n \
<a href=\"/?value=100\"><button>100</button></a><br>\n \
</body></html>\n";


// wifi client
void initwifi() {
ESP.wdtFeed();
WiFi.setAutoReconnect(true);
WiFi.mode(WIFI_STA);
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
int i = 0;
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
if (i > 40) {
Serial.print("No wifi connection. Restarting ESP...");
ESP.reset();
}
i++;
ESP.wdtFeed();
delay(500);
}
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
ESP.wdtFeed();
}


// http pyyntö juureen
void handle_root() {
ESP.wdtFeed();
String s = "";
int v = -1;
// Onko get- parametreja ? (ei pakollinen testi paitsi jos tehdään jotain eri tavalla riippuen siitä onko parametreja ollenkaan)
if (server.args() > 0) {
// Löytyykö pyyntö value=xxx
if (server.hasArg("value")) {
s = server.arg("value");
// parametrin arvo talteen ja yritetään muuttaa se numeroksi
// HUOM: toInt() palauttaa 0 jos arvoa ei voi muuntaa numeroksi.
// oikeasti pitäisi vielä testata jos v = 0 ja s != "0" => virheellinen syöte, ei tehdä mitään.
v = (int)s.toInt();
Serial.print("new input value = ");
Serial.println(v);
if ((value >= 0) && (value <= 100)) {
value = v;
} else {
Serial.print("invalid input, must be between 0 and 100: '");
Serial.print(v);
Serial.println("'");
}
}
}
// Tehdään kopio sivusta koska String.replace() korvaa pakalla eikä palauta mitään
String outpage = webPage;
// Oletusviesti = ei mitään
String message = "";
// Jos arvo on välillä 0-100 näytetään se viestinä
if ((value >= 0) && (value <= 100)) {
message = " Value = ";
message += value;
}
outpage.replace("@@MESSAGE@@", message);
server.send(200, "text/html", outpage);
ESP.wdtFeed();
}


// http pyyntö jota ei ole olemassa => näytetään perus- sivu
void handle_not_found() {
String outpage = webPage;
outpage.replace("@@MESSAGE@@", "");
server.send(200, "text/html", outpage);
ESP.wdtFeed();
// Toinen vaihtoehto on palauttaa "ei löydy"- virhe:
//server.send(404, "text/plain", "ERROR");
}


// Setup
void setup(void) {
// Sarjaportti
Serial.begin(115200);
Serial.println("Startup");

// wifi setup erillisessä funktiossa
Serial.println("setup wifi");
initwifi();

// http setup, eli juuren handler ja ei löydy- handler
server.on("/", handle_root);
server.onNotFound(handle_not_found);
server.begin();
Serial.println("HTTP server started");
}


void loop() {
// Jos wifi on poissa, yritetään yhdistää uudelleen
if (WiFi.status() != WL_CONNECTED) {
Serial.println("wifi lost! Reconnecting...");
initwifi();
}

// Jos arvo on muuttunut edellisestä tehdään jotain
if (value != prev_value) {

Serial.print("loop: value change ");
Serial.print(prev_value);
Serial.print(" => ");
Serial.println(value);

prev_value = value;

}

// http- pyyntöjen hanskaus
server.handleClient();
ESP.wdtFeed();
}
 
Liittynyt
19.10.2016
Viestejä
783
Kiitos @ississ viestistä. Lueskelin sitä tuossa läpi, mutta pitänee lukea pykälää tarkemmin koska kirjoittelit sinne paljon mielenkiintoista avartavaa kamaa. Eli lisään tuonne iltalukemisen joukkoon tämän. Nopeasti testasin sketchin läpi ja sain sillä kortin yhdistämään wifiin, servon kääntäminen ei tosin jostain syystä tällä enää toiminut. Compilessa ei virheitä tullut, joten tuolla lienee nyt vain jokin kohta hieman eri tavalla kuin mitä siinä alkuperäisessä (tai jotain). Yritän tutkia kun saan kaiken informaation mutusteltua.

Tilanne kokonaisuudessaan on nyt se, että saan ESP:n verkkoon ja servon kääntymään käyttäen sitä alkuperäistä sketchiä teidän avustamilla höystellä wifin suhteen. Tämä ei kuitenkaan vielä tarkoita, että kaikki kunnossa. Nyt pitäis tähän sketchiin liittyen seuraavaksi ymmärtää servon ohjauksien säätäminen vastaamaan tämän minulla olevan servon ominaisuuksia.
 
Liittynyt
17.01.2018
Viestejä
797
Kiitos @ississ viestistä. Lueskelin sitä tuossa läpi, mutta pitänee lukea pykälää tarkemmin koska kirjoittelit sinne paljon mielenkiintoista avartavaa kamaa. Eli lisään tuonne iltalukemisen joukkoon tämän. Nopeasti testasin sketchin läpi ja sain sillä kortin yhdistämään wifiin, servon kääntäminen ei tosin jostain syystä tällä enää toiminut. Compilessa ei virheitä tullut, joten tuolla lienee nyt vain jokin kohta hieman eri tavalla kuin mitä siinä alkuperäisessä (tai jotain). Yritän tutkia kun saan kaiken informaation mutusteltua.

Tilanne kokonaisuudessaan on nyt se, että saan ESP:n verkkoon ja servon kääntymään käyttäen sitä alkuperäistä sketchiä teidän avustamilla höystellä wifin suhteen. Tämä ei kuitenkaan vielä tarkoita, että kaikki kunnossa. Nyt pitäis tähän sketchiin liittyen seuraavaksi ymmärtää servon ohjauksien säätäminen vastaamaan tämän minulla olevan servon ominaisuuksia.
Joo, siinä viimeisessä esimerkissä ei ole servoa mukana ollenkaan, ei sen kuulukaan kääntyä :)
Pala kerrallaan eteenpäin, tässä oli vain wifi + reconnect ja http get paramerin luku.

Tuossa esimerkissä on siis ideana se että purkille voi antaa numeron välillä 0-100 ja arvo tallennetaan globaaliin muuttujaan "value".
Sen mukaan mitä oikeasti pitää tehdä arvoa voi käyttää suoraan web- handlerissa tai loopissa kuten esimerkissä (esimerkissä vain tulostetaan vanha ja uusi arvo).

Kumpikin tapa on hyvä sisäistää. Servon paikan voi asettaa suoraan handlerissa ja silloin ei tarvitse ehkä tehdä mitään loopissa.
Mutta jos arvo olisi vaikka kellonaika jolloin pitää tehdä jotain niin arvo pitää tallentaa handlerissa ja loopissa testataan onko aika tehdä se jokin.
 
Liittynyt
19.10.2016
Viestejä
783
:D okei, mä hötkyilin taas. Kiitos infosta. Koitan tuohonkin tosiaan perehtyä kun tältä informaatioähkyltä kykenen. On nyt monta rautaa tulessa, koska tähän löytyi jo muutama muukin sketch jota ihmiset ovat omatoimisesti itselleen muokanneet. Enkä tiedä onko koodareille tyypillistä, mutta jokaisen oma koodit tuntuvat olevan koodarin mielestä aina parhaita :)

Onko Sinulla tai jollakin ketjulaisella ymmärrystä, mikä tämän alkuperäisen servo-ohjauksen logiikka edes on:

C++:
server.on("/", []() { server.send(200, "text/html", webPage); });
server.on("/100", []() { server.send(200, "text/html", webPage); setting = 180; });
server.on("/99", []() { server.send(200, "text/html", webPage);  setting = 180; });
server.on("/98", []() { server.send(200, "text/html", webPage);  setting = 180; });
server.on("/97", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/96", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/95", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/94", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/93", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/92", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/91", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/90", []() { server.send(200, "text/html", webPage);  setting = 162; });

server.on("/89", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/88", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/87", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/86", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/85", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/84", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/83", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/82", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/81", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/80", []() { server.send(200, "text/html", webPage);  setting = 144; });

server.on("/79", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/78", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/77", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/76", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/75", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/74", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/73", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/72", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/71", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/70", []() { server.send(200, "text/html", webPage);  setting = 126; });

server.on("/69", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/68", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/67", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/66", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/65", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/64", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/63", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/62", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/61", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/60", []() { server.send(200, "text/html", webPage);  setting = 108; });

server.on("/59", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/58", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/57", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/56", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/55", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/54", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/53", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/52", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/51", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/50", []() { server.send(200, "text/html", webPage);  setting = 90; });

server.on("/49", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/48", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/47", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/46", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/45", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/44", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/43", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/42", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/41", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/40", []() { server.send(200, "text/html", webPage);  setting = 72; });


server.on("/39", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/38", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/37", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/36", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/35", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/34", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/33", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/32", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/31", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/30", []() { server.send(200, "text/html", webPage);  setting = 54; });

server.on("/29", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/28", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/27", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/26", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/25", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/24", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/23", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/22", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/21", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/20", []() { server.send(200, "text/html", webPage);  setting = 36; });

server.on("/19", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/18", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/17", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/16", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/15", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/14", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/13", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/12", []() { server.send(200, "text/html", webPage);  setting = 18; });
server.on("/11", []() { server.send(200, "text/html", webPage);  setting = 18; });
server.on("/10", []() { server.send(200, "text/html", webPage);  setting = 18; }); 

server.on("/9", []() { server.send(200, "text/html", webPage);   setting = 18; });
server.on("/8", []() { server.send(200, "text/html", webPage);   setting = 18; });
server.on("/7", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/6", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/5", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/4", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/3", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/2", []() { server.send(200, "text/html", webPage);   setting = 0; });
server.on("/1", []() { server.send(200, "text/html", webPage);   setting = 0; });
server.on("/0", []() { server.send(200, "text/html", webPage);   setting = 0; });
  server.begin();
  Serial.println("HTTP server started");
}

Kun sketch on tehty 180asteen servolle, niin tarkoittaako tämä, että "100" on servon asteina 180 (eli tuo ihan ylin rivi). Ja sitten päin vastoin alin rivi "0" on servon asteina pyöreä nolla (eli toinen ääripää servon kyvystä pyörittää)? Jos tarkoittaa, niin..
- voinko määrittää ylimmälle riville 270asteen maksimin näin:
server.on("/100", []() { server.send(200, "text/html", webPage); setting = 270; });

..jolloin servo kääntyisi "100":lla täydet 270 astetta.
 
Liittynyt
17.01.2018
Viestejä
797
:D okei, mä hötkyilin taas. Kiitos infosta. Koitan tuohonkin tosiaan perehtyä kun tältä informaatioähkyltä kykenen. On nyt monta rautaa tulessa, koska tähän löytyi jo muutama muukin sketch jota ihmiset ovat omatoimisesti itselleen muokanneet. Enkä tiedä onko koodareille tyypillistä, mutta jokaisen oma koodit tuntuvat olevan koodarin mielestä aina parhaita :)
Hyvä koodi
1. toimii oikein
2. on järkevästi jäsennelty ja muuttujan nimetty
3. on muidenkin kuin tekijän ymmärrettävissä järkevässä ajassa
4. mielellään kommentoitu riittävästi

Edit: ja niin kuin usein sattuu niin tuossa omassakin oli virhe, pitää tietysti olla
Koodi:
if ((v >= 0) && (v <= 100)) {
    value = v;
}
Eikä
Koodi:
if ((value >= 0) && (value <= 100)) {
    value = v;
}
Onko Sinulla tai jollakin ketjulaisella ymmärrystä, mikä tämän alkuperäisen servo-ohjauksen logiikka edes on:
Enpä oikeastaan katsonut mitä sen oikeasti pitäisi tehdä...
Mutta onko oikeasti tarkoitus että nuo nappulat 0-100 ovat kuin prosentteja koko liikealueesta, 0 toisessa laidassa ja 100 toisessa ?
Jos näin niin silloin riittää vain handlerissä katsoa mikä luku saatiin ja asettaa servon asento sen mukaan skaalattuna sille välille joka halutaan fyysisesti liikkua (niille arvoille joita kirjasto haluaa inputiksi).

Edit: Alkuperäinen koodi on tehty niin että servolle annetaan signaalia vain niin kauan kuin sen on tarkoitus liikkua. Siksi loopissa on mukana servoA.attach() ja detach().
Koodi:
void loop() {

    // ...

    if(position < setting){
        // Kasvatetaan servon paikka- arvoa yksi kerrallaan joka loopin kierroksella kunnes saavutetaan asetettu arvo.
        // Viive tarvitaan koska oikeasti loop() on paljon nopeampi kuin reaalimaailman servo.
        // Sarjaporttiin tulostus on myös viive loopissa eli jos sen ottaa pois niin voi joutua lisäämään delay- arvoa.
        // Jos delay on liian pieni niin paikka- asetus menee liian nopeasti ja servo ei ehdi perille asti ennen kuin
        // signaali lopetetaan ( servoA.detach() lopussa kun position == setting ).
        servoA.attach(servoPin);
        servoA.write(position++);
        delay(5);
        Serial.print("Setting: ");
        Serial.println(setting);
        Serial.print("Position: ");
        Serial.println(position);
    }
   
    if(position > setting){
        // Sama kuin yllä mutta toiseen suuntaan
        servoA.attach(servoPin);
        servoA.write(position--);
        delay(5);
        Serial.print("Setting: ");
        Serial.println(setting);
        Serial.print("Position: ");
        Serial.println(position);
    }
   
    if(position == setting){
        // Poistetaan servon signaali kun ollaan perillä
        servoA.detach();
    }

    // ...
}
Virransäästön kannalta on hyvä että signaali katkaistaan jos liikutettava kohde on sellainen jota ei tarvitse pitää aktiivisesti paikallaan.

Saattaa olla että "turvallisempi" vaihtoehto olisi tehdä lisätesti liikkeen alkuun kuten alla jolloin attach() kutsuttaisiin vain kerran.
Koodi:
int moving = 0;

void loop() {
    // ....

    if (position < setting) {
        if (moving == 0) {
            servoA.attach(servoPin);
            moving = 1;
        }
        servoA.write(position++);
        delay(5);
    }

    // ....
}
detach()- toiminnallisuuden voisi sitten toteuttaa vaikka ajastimella joka laukeaa tietyn ajan kuluttua liikkeen alkamisesta. Yksinkertaisimmillaan se voisi olla tyyliin 10 sekuntia jolloin melkein mikä tahansa servo ehtii maaliin. Tai ajan voisi laskea liikkeen lähtöhetkellä edellisen ja uuden asetuksen erotuksena.


Kun sketch on tehty 180asteen servolle, niin tarkoittaako tämä, että "100" on servon asteina 180 (eli tuo ihan ylin rivi). Ja sitten päin vastoin alin rivi "0" on servon asteina pyöreä nolla (eli toinen ääripää servon kyvystä pyörittää)? Jos tarkoittaa, niin..
- voinko määrittää ylimmälle riville 270asteen maksimin näin:
server.on("/100", []() { server.send(200, "text/html", webPage); setting = 270; });

..jolloin servo kääntyisi "100":lla täydet 270 astetta.
Jos tuo on tarkoitettu ns. rc- servoille niin niissä on virallisesti keskikohta 0 ja kääntökulma yleensä +- jotain astetta. Valmistajasta riippuen keskikohtakin on eri paikassa jolloin ainakin omasta mielestäni olisi vähän hassua tehdä kirjasto jossa 0 on jossain toisessa laidassa eikä keskellä.
Mutta kaikki on mahdollista ja kyseinen tieto pitäisi löytyä kirjaston omasta dokumentaatiosta.

Mutta periaatteessa kyllä, jos 0 on toinen pää niin toinen on sitten joku isompi luku.

Tosin varmista ensin kuinka paljon käyttämäsi servo osaa kääntyä, kaikki eivät pääse edes tuohon 180 asteeseen enkä ole nähnyt purjevinssiä lukuunottamatta yhtään joka osaisi 270 astetta. Osassa on fyysiset esteet ettei käänny ympäri.

Edit: varmuuden vuoksi testasin, ensimmäinen käteen osuva oli Futaba S5105 jonka fyysinen liikealue on arviolta 185 astetta. Toisessa päässä asetus 0 jättää liikkeen muutaman asteen päähän rajasta ja toisessa päässä 175 on turvallinen maksimi.
Signaalina nuo paikat vastaavat 0 => 0.5ms ja 175 => 2.3ms. Testiservon keskikohta on virallisesti 1.5ms ja 100% liikealue muistaakseni 1.0ms - 2.0ms.
Käytetyn servon ominaisuudet siis kertovat kuinka paljon sitä voi kääntää.

Sen sijaan että tekee noilla erillisillä server.on() kutsuilla niin voit mapata annetun arvon halutulle välille valmiilla funktiolla. Esimerkiksi näin:
Koodi:
setting = map(value, 0, 100, 5, 170);
Tuossa siis välillä 0-100 oleva arvo skaalataan uudelleen välille 5-170. Paljon vähemmän kirjoittamista kuin tehdä jokaiselle oma server.on().
Jos liikealueen ei kuulu olla suora tai muuta vastaavaa niin sitten voi tehdä taulukon jossa on 100 arvoa:
Koodi:
// Tuohon 100 haluttua arvoa peräkkäin
int settingValues[] = { 5, 5, 6, 6, 7, 7, .... jne ... , 170, 170 }

// ja arvon haku taulukosta
setting = settingValues[value];
 
Viimeksi muokattu:
Liittynyt
19.10.2016
Viestejä
783
Enpä oikeastaan katsonut mitä sen oikeasti pitäisi tehdä...
Mutta onko oikeasti tarkoitus että nuo nappulat 0-100 ovat kuin prosentteja koko liikealueesta, 0 toisessa laidassa ja 100 toisessa ?
Jos näin niin silloin riittää vain handlerissä katsoa mikä luku saatiin ja asettaa servon asento sen mukaan skaalattuna sille välille joka halutaan fyysisesti liikkua (niille arvoille joita kirjasto haluaa inputiksi).
Juu nappulat ovat nyt siis omien testieni perusteella prosentteja koko liikealueesta.

Jos tuo on tarkoitettu ns. rc- servoille niin niissä on virallisesti keskikohta 0 ja kääntökulma yleensä +- jotain astetta. Valmistajasta riippuen keskikohtakin on eri paikassa jolloin ainakin omasta mielestäni olisi vähän hassua tehdä kirjasto jossa 0 on jossain toisessa laidassa eikä keskellä.
Mutta kaikki on mahdollista ja kyseinen tieto pitäisi löytyä kirjaston omasta dokumentaatiosta.

Mutta periaatteessa kyllä, jos 0 on toinen pää niin toinen on sitten joku isompi luku.

Tosin varmista ensin kuinka paljon käyttämäsi servo osaa kääntyä, kaikki eivät pääse edes tuohon 180 asteeseen enkä ole nähnyt purjevinssiä lukuunottamatta yhtään joka osaisi 270 astetta. Osassa on fyysiset esteet ettei käänny ympäri.
Juu tuollaisen DS3218MG servo kyseessä:
"High Rotation - well-controlled, 270 degree rotation. 360 degree rotation when power-off, perfect for robot joint activities".

Ja nyt kun asiaa tutkin, niin servo kääntyy jo valmiiksi sen 270astetta kun klikkaan 100%. Jos klikkaan 0% niin palaa takaisin toiseen ääripäähän 270astetta. En kuitenkaan ymmärrä mitä tuo 180 esim. siinä koodiosan ylimmässä rivissä tarkoittaa:

server.on("/100", []() { server.send(200, "text/html", webPage); setting = 180; });

Tässähän itse pohdin, että voin tuon 180 korvata 270:llä, mutta kun servo jo nyt pyörähtää 270 tuolla ylimmän rivin 100% napilla niin mikä hitto tuo 180astetta sitten on.
 
Liittynyt
17.01.2018
Viestejä
797
Juu nappulat ovat nyt siis omien testieni perusteella prosentteja koko liikealueesta.

Juu tuollaisen DS3218MG servo kyseessä:
"High Rotation - well-controlled, 270 degree rotation. 360 degree rotation when power-off, perfect for robot joint activities".

Ja nyt kun asiaa tutkin, niin servo kääntyy jo valmiiksi sen 270astetta kun klikkaan 100%. Jos klikkaan 0% niin palaa takaisin toiseen ääripäähän 270astetta. En kuitenkaan ymmärrä mitä tuo 180 esim. siinä koodiosan ylimmässä rivissä tarkoittaa:

server.on("/100", []() { server.send(200, "text/html", webPage); setting = 180; });

Tässähän itse pohdin, että voin tuon 180 korvata 270:llä, mutta kun servo jo nyt pyörähtää 270 tuolla ylimmän rivin 100% napilla niin mikä hitto tuo 180astetta sitten on.
Tulikin samaan aikaan vielä muokattua tuota edellistä...

Servokirjasto olettaa että servo kääntyy 180 astetta pulssivälillä 544 - 2400us.
Jos servosi kääntyy enemmän asetuksella 180 niin silloin pitää käyttää pienempää asetusarvoa. Kokeile millä arvoilla 0-180 välillä saat oikean kokoisen liikealueen.
Oletetaan että servo kääntyisi riittävästi välillä 25-105. Silloin 0-100% välillä annetusta syötteestä saadaan servokirjastolle sopiva esimerkiksi näin:
Koodi:
setting = map(input, 0, 100, 25, 105);
servoA.write(setting);
Kannattaa myös lukea mitä se kirjasto oikeasti tekee: servo.cpp
Siellä on esimerkiksi tekijän mukaan tarkempi map() toteutus jota kirjasto itse käyttää.
Write()- funktio tekee sisäisesti value = improved_map(value, 0, 180, _minUs, _maxUs); eli se mäppää 0-180 astetta min-max alueelle joka on oletuksena 544 - 2400 (löytyy Servo.h).

Eli testaa liikkeen rajat ja sitten koodissa map prosenttiarvosta servokirjastolle sopiviin rajoihin.
 
Liittynyt
19.10.2016
Viestejä
783
Kiitos taas. Olet kyllä melkoinen äijä kun tänne näin kattavasti kirjoittelet!!

Servot tunkeutuivat jopa yöuniin, ja heräsin ajatukseen, että mitä tuon asetusarvon muokkaaminen yleensäkään auttaa meikäläisen tapauksessa. Kun servo nyt kääntyvät nykyisellä 180konfatulla sketchilla jo sen 270astetta, niin tuossa lienee se koko kapasiteetti pakosti käytössä.
 
Liittynyt
17.01.2018
Viestejä
797
Kiitos taas. Olet kyllä melkoinen äijä kun tänne näin kattavasti kirjoittelet!!

Servot tunkeutuivat jopa yöuniin, ja heräsin ajatukseen, että mitä tuon asetusarvon muokkaaminen yleensäkään auttaa meikäläisen tapauksessa. Kun servo nyt kääntyvät nykyisellä 180konfatulla sketchilla jo sen 270astetta, niin tuossa lienee se koko kapasiteetti pakosti käytössä.
Rajat pitäisikin hakea siksi ettei päädy tilanteeseen jossa servon liike on jo tapissa esim 80% asetuksella jolloin loput 80-100 säädöstä on turhaa kun servo ei enää liiku...
 
Liittynyt
19.10.2016
Viestejä
783
Mutta kun tuo kokonaisuus näyttää toimivan siten, että 100% = 270astetta, ja 0% = 0astetta. Eli ei tuo edes oleta, että 180 astetta olisi maksimi, sitä tässä hämmästelen, että eikö oikeasti määritetyllä 180max asteella ole mitään merkitystä toimintaan kun ei tunnu olevan.
 
Liittynyt
17.01.2018
Viestejä
797
Mutta kun tuo kokonaisuus näyttää toimivan siten, että 100% = 270astetta, ja 0% = 0astetta. Eli ei tuo edes oleta, että 180 astetta olisi maksimi, sitä tässä hämmästelen, että eikö oikeasti määritetyllä 180max asteella ole mitään merkitystä toimintaan kun ei tunnu olevan.
Tarkoitinkin sitä jos 90 tai 95 ja 100 välillä servo ei enää liiku niin sitten pitää ehkä säätää. Tai jos servo liikuttaa jotakin jolla on fyysiset rajat ja liikealuetta pitää säätää ettei yritä vääntää jotain rikki.

Toimintaan vaikuttaa se kuinka paljon servo liikkuu signaalin mukaan. Kirjasto olettaa että keskiasento on "vakio" 1520us ja rajat 544us - 2400us joilla "suurin osa servoista" liikkuu "suunnilleen 180 astetta".
Tässä tapauksessa tuo servo todennäköisesti liikkuu enemmän / us koska sen liikealue on 270 eikä 180 astetta.
=> Käy niin että normaaliservolla kirjastolle annettu astemäärä vastaa aika tarkkaan oikeaa kääntökulmaa ja 270 asteen servo kääntyy samalla asetuksella enemmän (pikalaskulla liike on 1.5 * asetettu astemäärä).
Sama tapahtuisi esimerkiksi purjevinssiservolla jossa liikealue on tyyliin10 kierrosta. Silloin 0 olisi liikealueen toisessa laidassa ja 180 kääntäisi koko 10 kierrosta koska servon signaali on edelleen sama 0.5ms ... 2.4ms liikealueesta riippumatta.

Toivottavasti muistin jo aikaisemmin mainita että kirjasto olettaa tiettyjä asioita (esimerkiksi montako astetta servo kääntyy / us) ja mitkä ovat signaalin rajat. Kirjasto ei voi millään tietää liikkuuko fyysinen servo keskialueesta 60 astetta, 135 astetta vai 20 kierrosta. Ja sen vuoksi astemäärä ei ole kaikille servoille sama eikä aina vastaa reaalimaailman liikettä.
Jos käytät koodissa servo.write() sijaan servo.writeMicroseconds() niin tuosta häviää hämäävä asteluku. Jokainen servo kuitenkin tottelee tiettyä pulssin pituutta ja sen pituuden muutoksen suhde astelukuun riippuu servosta.

Eli oikeastaan pitää unohtaa että se luku on asteita ja ajatella niin että liikealue on vain väli arvosta x arvoon y olivatpa arvot mitä tahansa.
Käyttöliittymän kannalta asetus reunasta toiseen on 0-100% jonka pitää vastata tiettyä reaalimaailman liikettä, esimerkiksi laidasta laitaan 270 astetta.
Koodissa sitten tehdään mäppäys annetusta 0-100 arvovälistä siihen arvoväliin jolla saadaan aikaan haluttu reaaliliike niin ettei asetusvälillä ei ole tyhjää tai liike ei yritä olla liian iso.
 
Toggle Sidebar

Statistiikka

Viestiketjut
89 646
Viestejä
1 832 612
Jäsenet
39 018
Uusin jäsen
slyersly

Hinta.fi

Ylös Bottom