Arduino -ketju (kysymykset/keskustelu)

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).
 
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();
}
 
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
 
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ä.
 
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();
}
 
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.
 
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.
 
: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.
 
: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:
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.
 
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.
 
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ä.
 
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...
 
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.
 
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.
 
Tulipa hommattua tällaisia ihan mielenkiinnosta testiin LGT8F328P aliexpress ja yllätyin positiivisesti. Pähkinänkuoressa kyseessä on 99% arduino nanon kanssa yhteensopiva kopio about puolet halvempaan hintaan. Tässä nanokopiossa on kaiken lisäksi vielä extra-arvoa verrattuna nanoon, laiskana lisään vain kuvakaappauksen youtubesta kun en jaksa alkaa luettelemaan. Ja ettei unohdu mainita niin ovat varustettu uudemmalla micro usb liittimellä. Löytyy myös pro micron korvaava malli, mutta siitä en osaa sanoa itse mitään.
1595698785420.png

Käyttöönotto oli todella helppoa. Additional board manager urleihin tämä: https://raw.githubusercontent.com/dbuezas/lgt8fx/master/package_lgt8fx_index.json minkä jälkeen boards managerin kautta asennus. Eli ihan perus settiä jos esp32/8266 tai stm32 ovat entuudestaan tuttuja. Ao. github linkissä ja youtube videossa lisää tietoa asennuksesta yms.




Piti tehdä tilaus ja hommata näitä jemmaan ensitestien jälkeen. Tällä hinnalla kyllä korvaavat omassa käytössä nanon ellei ilmaannu ongelmia tai jokin puute.

edit. Korjailtu ja lisäilty tekstiä.
 
Viimeksi muokattu:
Ideaa missä ongelma?

Eli tarkoituksena ohjata lähtökohtaisesti kattovaloja IR-vastaanottimen avulla, mutta nyt protossa ohjaan yksinkertaistettuna kahta eri lediä. Pitäisi saada led1 syttymään samalla kun Arduinoon tulee virta. Valmista koodia jota hieman muokannut, muuten pelaa erinomaisesti. Nyt koodi toimii niin, että kumpikin led syttyy vuorollaan, kun painan niiden omaa nappulaansa. Arduino kytkettäessä valot sammuneena.

Ei auta, vaikka muokkaan koodia ---> int itsONled[] = {0,0,0,0}; ,niin että vaihdan nollia ykköseksi. Tähän tyyliin ---> int itsONled[] = {0,1,1,0}; Ainoa muutos jonka tuo aiheuttaa on se, että periaatteessa ledit ovat päällä ohjelmassa, sillä ne eivät syty kaukosäätimellä, vaan eka painallus ei tee mitään "vaan periaateessa sammuttaa ledin" ja toisella painalluksella vasta syttyy.

Myös alemmas koittanut säätää, mutta ei onnistu. Suoraa ideaa jollakin?

Koodi:
#include <IRremote.h>


int RECV_PIN = 3; // the pin where you connect the output pin of TSOP4838

int led1 = 2;

int led2 = 4;

int led3 = 7;

int itsONled[] = {0,0,0,0};


/* the initial state of LEDs is OFF (zero)

the first zero must remain zero but you can

change the others to 1's if you want a certain

led to light when the board is powered */


#define code1  3772818013 // code received from button A

#define code2  3772834333 // code received from button B

#define code3  22695 // code received from button C


IRrecv irrecv(RECV_PIN);


decode_results results;


void setup()

{

  Serial.begin(9600);   // you can comment this line

  irrecv.enableIRIn();  // Start the receiver

  pinMode(led1, OUTPUT);

  pinMode(led2, OUTPUT);

  pinMode(led3, OUTPUT);

}


void loop() {

  if (irrecv.decode(&results)) {

    unsigned int value = results.value;

    switch(value) {

       case code1:

         if(itsONled[1] == 1) {        // if first led is on then

            digitalWrite(led1, LOW);   // turn it off when button is pressed

            itsONled[1] = 0;           // and set its state as off

         } else {                      // else if first led is off

             digitalWrite(led1, HIGH); // turn it on when the button is pressed

             itsONled[1] = 1;          // and set its state as on

         }

          break;

       case code2:

         if(itsONled[2] == 1) {

            digitalWrite(led2, LOW);

            itsONled[2] = 0;

         } else {

             digitalWrite(led2, HIGH);

             itsONled[2] = 1;

         }

          break;

       case code3:

         if(itsONled[3] == 1) {

            digitalWrite(led3, LOW);

            itsONled[3] = 0;

         } else {

             digitalWrite(led3, HIGH);

             itsONled[3] = 1;

         }

          break;   

    }

    Serial.println(value); // you can comment this line

    irrecv.resume(); // Receive the next value

  }

  delay(500);

}


Koodisi ei muuta lähtöjen tilaa vastaamaan vektoriin tallettamiasi arvoja ennen loopin suorittamisen aloittamista. Muuttujien arvot ja lähtöjen tilat eivät siis automaattisesti ole kytköksissä toisiinsa, arvot pitää kirjoittaa lähtöihin.
Pinnien lähdöiksi määrittämisen jälkeen tarvitaan siis jotakin tälläistä:
Koodi:
digitalWrite(led1, itsONled[1]);
digitalWrite(led2, itsONled[2]);
digitalWrite(led3, itsONled[3]);
 
Olisiko keneläkään ideaa, mikä on vikana.
Ongelmana on että arduino leonardo ei tunnistaudu peliohjaimena vaan näppäimistönä.
Ongelma tuli Windowssin uudelleen asentamisen jälkeen.
Kyseessä on ebaysta tilattu analoginen USB käsijarru.
Läppärillä kyseinen laite toimii oikein hyvin, mutta ei pöytäkoneella.
 
Tuli vaihdettua arduinoista PIC-maailmaan ja näin alkuvaiheessa oman dev-boardin valmistamisen ja ensimmäisten esimerkkien jälkeen tuntuu että heti on jo saanut miljoona kertaa enemmän irti koko touhusta. Tuntuu siltä että näiden parissa on oikeasti jopa mahdollista oppia jotain uutta elektroniikasta ja ohjelmoinnista. Tarkoituksena ei nyt ole ottaa kantaa että kumpi on parempi, kun itsellänikään ei ole siitä mielipidettä enkä edes tiedä näistä tarpeeksi haukkuakseni toista huonommaksi tai kehuakseni toista paremmaksi.

Muistaakseni en kertaakaan ole joutunut kaivamaan atmega328 datalehteä ymmärtääkseni miten joku asia toimii, mutta heti kun osti muutaman erilaisen (vanhempaa ja uudempaa, 28 ja 40 pinnistä) picin niin joutunut kyllä avaamaan sen datalehden kun asiat ovat muuttuneet hieman vuosien saatossa. Ja itselleni tämä on positiivinen asia kun joutuu oikeasti vähän päättelemään että mikäs on kun asia ei pelitäkään samalla tavalla uudella ja vanhalla piirillä. Toki uskon että avr vehkeiden kanssa törmää hyvin todennäköisesti samaan jos käyttää jotain muuta kuin arduino IDE:ä :hmm:.

Oman levyn suunnittelun lisäksi ostin mouserilta microchipin valmistaman Curiosity Hpc dev-boardin ~40€? hintaan varmuuden vuoksi jos omassa suunnittelussa ilmeneekin jotain vikaa, sekä 40 pinnisten käyttöä varten. Äkkiseltään yksinkertainen käyttää ja toimii nätisti usbin yli eikä tarvitse tuota pickitiä ohjelmointiin, mutta toisaalta itse katson kauhulla tuota levyä kun se on ahdettu niin täyteen pientä sälää. Saa nähdä koska nousee savut kun on niin paljon mitä pystyy yhdellä levyllä kerralla hajottamaan.

Tässä kun on hieman vauhtiin päässyt niin suunnittelupöydällä on myös oma levy mihin voisi myöskin laittaa 28/40 pinnisen picin. Ajattelin myös, että tulevaisuutta silmällä pitäen levyllä olisi paikka oled/lcd-näytölle ja esp8266 tai nrf24 radiolle, mutta saa nähdä koska tuon ehtii ja jaksaa tehdä loppuun. Levyjen suunnittelu tuo näihin touhuihin aina oman kivan "pienen" lisämausteen.

pic.jpg
 
Se helppoushan on Arduinon idea ainakin IDEn/koodin osalta niin kauan kuin käyttää vain arduino- kirjastoja.

@pinppi jos oikeasti haluat ymmärtää miten Arduino (raudassa) asiat tehdään niin ihan samalla tavalla pitää ottaa datalehti käteen kuin piceissäkin. Arduinosoftassa asioita on pureksittu valmiiksi ja nostettu ylemmälle tasolle juuri siksi että aloituskynnys olisi matalampi.
Tuota sun pic- kokemusta vastaisi se että ostat kaupasta pelkän AVR:n ja haet Atmel Studion. Silloin ilman datalehteä ei pääse liikkeelle.

Itse käytän muutamaa Arduino- korttia labrailuun kun en viitsi tehdä omaa protokorttia mutta Arduino IDEen en koske koska sillä ei oikeasti tee mitään jos haluaa vähänkin monimutkaisempia juttuja.
Monet koodinpätkät on helppo testata arduinoraudassa koska niitä ja klooneja saa järkevällä hinnalla. Parissa projektissa olen käyttänyt arduino- korttia lopputuloksessakin (mega2560 kun liittimet oli valmiina ja pari 32u4- korttia näppäimistöille ) mutta missään ei ole arduinokirjastoja/softaframea käytössä.

Tuohon esp8266 liittyen kannattaa todennäköisesti unohtaa sen käyttö vain "verkkokorttina" ja tehdä suoraan koko koodi pyörimään esp:ssä. Potkua löytyy enemmän kuin avr:ssä ja miksi laittaa 2 palikkaa kun sen voi tehdä yhdellä ? Lisäksi säästää piirien välisen hitaan kommunikoinnin...
 
Ymmärrän kyllä ja mainitsin itsekin jo aikaisemmassa viestissäni että avr-palikoiden kanssa luultavasti sama homma kuin näiden piccien kanssa eli datalehti kiltisti kouraan. Ja kyllähän se tuon arduinon ja varsinkin iden tarkoituksena on nimenomaan tuo helppous ja sen tuoma nopeus. Kukin tyylillään, enkä tässä lähtenyt mitenkään sen jyrkemmin vetämään seiniä pystyyn ja sanomaan mitä kenenkin kannattaa ja ei kannata tehdä. Vaan itse päätin tehdä näin.

Sanon vain, että omalla kohdalla tuo arduino iden tuoma helppous on ollut ehkä lähinnä sudenkuoppa ja karhunpalvelus. Tuntuu, että on se sitten youtubesta jotain projektivideon katselua, practical electronicsin tai elektorin lukemista, instructablesia tai joku ohje sivustolla x, niin laulu menee about näin: Kopsaa kytkentä kokonaisuudessaan tai pienin muutoksin, lataa se ja se kirjasto ja vaihda koodissa i/o:t samoiksi kuin itse käytit ja syötä koodi levylle. Siis lyhykäisyydessään arduinoja voi käyttää niin että itse ei kirjoita pätkän pätkää koodia vaan kopsaa kaiken ja jos oma projekti ei ole kytkennän puolesta tismalleen samanlainen niin sen kuin kopsaa ja yhdistelee kahden eri projektin koodit jos osaa ja tajuaa vähääkään koko touhusta. Ja kyllä vika on myös käyttäjässä koska tiedän että kukaan ei pakota käyttämään valmista koodia/kirjastoja tai ylipäätänsä käyttäytymään näin, vaan asiat voisi tehdä vaikeimman kautta arduinojenkin kanssa :lol:. Mutta toisaalta koko ekosysteemihän nojaa aivan valtavasti tähän suuntaan ja yhä enenevissä määrin (stm32, esp32, esp8266, PIC, miljoona muuta). Ehkä olen vain tyhmä tai katson asioita väärästä näkökulmasta.

@ississ Kiitos tuosta esp8266 vinkistä. Tuota mietin lähinnä testailun vuoksi ja pohjalla tuollakin on se, että joutuisi kaivelemaan datalehteä espin ohjauksessa.
 
Noinhan se on, kukin käyttää sitä mistä itse pitää eikä siinä muilla ole sanomista.

esp on jo pykälää hankalampi jos haluaa käyttää valmistajan omaa sdk:ta, siihen melkein suosittelen arduinosoftaa ainakin alkuun, muuten menee aika hankalaksi (ainakin viimeksi kun katsoin niin sdkn dokumentaatiokin olin vähän niin ja näin). Ihan vastaavaa manuaalia kuin avr/pic ei muistaakseni ollut edes julkaistu esplle silloin kun kaivelin.

Stm ja muut vastaavat ovat jo aika haastavia tehdä alusta asti ellei nimenomaan halua opetella sillä tasolla. Mutta jos haluaa saada jonkin laitteen/toiminnallisuuden aikaan niin kannattaa ehkä käyttää vähän korkeamman tason juttuja kuin rautaa alimmalla nippelitasolla.

Jos käytät windowsia niin visual studio ja siihen visual micro lisäosa on hyvä yhdistelmä korvaamaan arduino iden jos käyttää arduinosoftaa pohjana. Voihan sen tehdä niinkin että pitää pohjan ja kirjoittaa muuten itse eikä käytä valmiita.
Omat esp- projektit on tehty arduinosoftan päälle jo siksi että en halunnut lähteä kirjoittamaan kaikkea itse vain opettelun halusta vaan tarkoituksena oli tehdä toimivia laitteita. Tosin eipä ne kaikki kirjastotkaan toimineet, mm ntp piti korjata ettei tullut virhettä...

Ja aina kuitenkin keskustelut systeemistä tai toisesta päätyy tähän:
1602092780689.png
 
Mistä olette hankkineet muuntajat Arduino projekteihin? Olen käyttänyt Wemos D1 minin kanssa vanhoja Nokian latureita mutta niitä ei ole riittävästi, että saisi kaikkiin virtaa.
 
Bilteman powereita aika useesti käyttänyt. Saa helposti, hinta ok ja varmaan joutuneet jonkunlaiseen syyniin turvallisuutensa puolesta euroopassa ( toki pelkkä olettamus).
 
Lidlin powerit tapaa olla aika lyömättömiä hinnan ja laadun suhteen. Harmi vaan kun saatavilla aika harvoin.
 
Aikaisemmin tehty arduinolla (mega ja nRF24L01 <-> mega ja nRf24L01) toimiva viritys jolla ohjataan 1:125 koko suhteessa olevaa MS Cinderellaa.
Uuudessa projektissa ohjataan veturia. TX-puoli mega ja nRf24L01 ja RX-puoli RF Nano. Jossakin vaiheessa tarkoitus saada 6 veturia yhden megan ojkauksen perään. Nyt ongelmana, että RF Nano ei suostu keskustelemaan. Ohjelmointi ei ole vahvuuteni, koodin voisi varmaan tehdä paremmaksi ja tehokkaammaksi.


C:
//Tässä TX-puolen koodi

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(9,10); // CE, CSN
const uint64_t pipes[2] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D1LL };

byte junanSuunta;
int potValueA0;                    //JUNAN TEHON MÄÄRITYS POTIKALLA

int tehoMaaritys = 0;

const int nappiPin1 = 2;             //JUNAN SUUNNAN MÄÄRITYS KYTKIMELLÄ
const int nappiPin2 = 4;             //JUNAN SUUNNAN MÄÄRITYS KYTKIMELLÄ
byte napinTila1 = 0;                 //JUNAN NAPIN TILATIETO TALLENNETTU
byte napinTila2 = 0;                 //JUNAN NAPIN TILATIETO TALLENNETTU

int laskuri10;
int laskuri = 10;                       // Monenko void loop lukukierroksen välein tulostetaan sarjamonitorin data

int     L1;
byte    L2;
byte    L3;
byte    L4;
byte    L5;
byte    L6;
byte    L7;
byte    L8;

int     K1;
byte    K2;
byte    K3;
byte    K4;
byte    K5;
byte    K6;
byte    K7;
byte    K8;


typedef struct {       // En tiedä monta kohtaa tässä voi olla mutta nämä liikkuu aina kerralla pakettina lähetyksessä ja vastaanotossa.
  int L1;
  byte L2;
  byte L3;
  byte L4;
  byte L5;
  byte L6;
  byte L7;
  byte L8;
} A_t;

typedef struct {
  int K1;
  byte K2;          
  byte K3;          
  byte K4;          
  byte K5;          
  byte K6;
  byte K7;
  byte K8;  
} B_t;
A_t Juna;

B_t Kauko;



void setup() {

  pinMode(A0, INPUT);                         //INPUT POTIKALLE
  pinMode(nappiPin1, INPUT);                  //INPUT SUUNTAKYTKIMELLE      
  pinMode(nappiPin2, INPUT);                  //INPUT SUUNTAKYTKIMELLE  


  Serial.begin(9600);
  radio.begin();
  radio.setPALevel(RF24_PA_MIN);             // MIN, LOW, MED, HIGH
  radio.setDataRate(RF24_250KBPS);           //set datarate to 250kbps
  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1, pipes[0]);
  radio.startListening();
}

void loop() {      

   laskuri10++;
   if (laskuri10 == (laskuri+1)) {
    laskuri10 = 0;
   }

junanteho();
junansuunta();

Kauko.K1 = tehoMaaritys;
Kauko.K2 = napinTila1;
Kauko.K3 = napinTila2;
//Kauko.K4 =
//Kauko.K5 =
//Kauko.K6 =
//Kauko.K7 =
//Kauko.K8 =

  delay(20);
  if (radio.available()) {

    radio.read( &Juna, sizeof(Juna) );


  }
    radio.stopListening();

    delay(30);

    bool ok = radio.write( &Kauko, sizeof(Kauko) );

    radio.startListening();

    if (laskuri10 == laskuri) {

      Serial.print(Kauko.K1);
      Serial.print(" / ");
      Serial.print(Kauko.K2);
      Serial.print(" / ");
      Serial.print(Kauko.K3);
      Serial.print(" / ");
}
}

void junanteho() {                                 //junan teho alkaa tästä

  potValueA0 = analogRead(A0);
  tehoMaaritys = map(potValueA0, 0, 1023, 0, 255);
}

void junansuunta() {                              //junan suunta alkaa tästä

  napinTila1 = digitalRead(nappiPin1);            //Luetaan suunta painonappi 1
  napinTila2 = digitalRead(nappiPin2);            //Luetaan suunta painonappi 2
}

//Tässä RX-puolen koodi

#include <nRF24L01.h>
#include <RF24.h>
#include <SPI.h>
#include <printf.h>

RF24 radio(9,10); // CE, CSN
const uint64_t pipes[2] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D1LL };

byte Suunta;
byte Teho;

// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

//Moottoriohjain pinnit

int Ohjaus_eteen = 5; //IC-piiri L9110 ohjaus, pinni
int Ohjaus_taakse = 6; //IC-piiri L9110 ohjaus, pinni
int Valo_eteen = 3; //Valoohjaus pinni
int Valo_taakse = 4; //Valoohjaus pinni
int Speed = 0; //Speed nollataan

// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx



typedef struct {
int L1;
byte L2;
byte L3;
byte L4;
byte L5;
byte L6;
byte L7;
byte L8;
} A_t;

typedef struct {
int K1; //
byte K2; //
byte K3; //
byte K4; //
byte K5; //
byte K6;
byte K7;
byte K8;
} B_t;
A_t Juna;
B_t Kauko;

// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

void setup()
{

pinMode(Ohjaus_eteen, OUTPUT); //Asetellaan ohjauspinnit ulostuloiksi
pinMode(Ohjaus_taakse, OUTPUT); //Asetellaan ohjauspinnit ulostuloiksi
pinMode(Valo_eteen, OUTPUT); //Asetellaan ohjauspinnit ulostuloiksi
pinMode(Valo_taakse, OUTPUT); //Asetellaan ohjauspinnit ulostuloiksi


Serial.begin(9600);
radio.begin();
radio.setPALevel(RF24_PA_MIN); // MIN, LOW, MED, HIGH
radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1, pipes[1]);


}

// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

void loop() {


radio.stopListening();

{

junanteho();
junansuunta();

}

Juna.L1 = Kauko.K1; //Potikan teho
Juna.L2 = Kauko.K2; //Suunta eteen määritys
Juna.L3 = Kauko.K3; //Suunta taakse määritys
//Juna.L4 =
//Juna.L5 =
//Juna.L6 =
//Juna.L7 =
//Juna.L8 =

bool ok = radio.write( &Juna, sizeof(Juna) );

radio.startListening();
if (radio.available()) {
Serial.print("PAALLA"); //Jos radio päällä niin kertoo sen
radio.read( &Kauko, sizeof(Kauko) );
}
delay(30);



Serial.print(" / ");
Serial.print(Kauko.K1);
Serial.print(" / ");
Serial.print(Kauko.K2);
Serial.print(" / ");
Serial.print(Kauko.K3);
Serial.print(" / ");

}

// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

void junanteho() //Teho ohjauksen koodia
{
Teho = Kauko.K1;
Speed = map(Teho, 0, 1023, 0, 255); // Muunnetaan alue sopivaksi
}


void junansuunta() //Suunta ohjauksen koodia
{

Ohjaus_eteen = Kauko.K2;
Ohjaus_taakse = Kauko.K3;

//ohjaus päälle (HIGH) tai pois (LOW)

if (Ohjaus_eteen == LOW && Ohjaus_taakse == HIGH)

{
digitalWrite(Ohjaus_eteen, LOW); // laitetaa ohjaus_eteen LOW tilaan
analogWrite(Ohjaus_taakse, Speed); // Asetetaan moottorien nopeus
}

if (Ohjaus_eteen == HIGH && Ohjaus_taakse == LOW)
{
digitalWrite(Ohjaus_taakse, LOW); // laitetaa ohjaus_eteen LOW tilaan
analogWrite(Ohjaus_eteen, Speed); // Asetetaan moottorien nopeus
}

}
 
Viimeksi muokattu:
Suositelkaas BLE-lisämoduuli Arduinoon etäisyyden voimakkuuden kasvattamiseks? Käytössä Arduino Nano 33 IoT
 
Tämä tuntui parhaalta paikalta kyseltä näistä lisää. Etsinnässä siis pitkällä kantomatkalla oleva hyvin yksinkertainen radio linkki, ajattelimpa kysyä onko kellään kokemuksia löytyykö mistään euroopasta tai peräti Suomesta tälläisiä tai vastaavia. Saa myös tarjoilla jos jollain on omissa hyllyissä ja suostuu myymään :)


 
Onko porukalla suosituksia, mistä kiinalaisesta kaupasta arduinoja ja niihin liittyvää elektroniikkaa kannattaa tilata?

Pitäisi saada muutamia kymmeniä arduino unoja, pari megaa ja nanoa, shieldejä, Bluetooth moduuleja, liittimiä yms, ja toivottavaa olis että nämä kaikki löytyis yhdestä ja samasta paikasta.

Chipskey kaupasta olen yrittänyt tilata, mutta mielluummin otan juurihoitoa ilman puudutetta ennenkuin asioin niiden asiakaspalvelun kanssa enempää.
 
Onko porukalla suosituksia, mistä kiinalaisesta kaupasta arduinoja ja niihin liittyvää elektroniikkaa kannattaa tilata?

Pitäisi saada muutamia kymmeniä arduino unoja, pari megaa ja nanoa, shieldejä, Bluetooth moduuleja, liittimiä yms, ja toivottavaa olis että nämä kaikki löytyis yhdestä ja samasta paikasta.

Chipskey kaupasta olen yrittänyt tilata, mutta mielluummin otan juurihoitoa ilman puudutetta ennenkuin asioin niiden asiakaspalvelun kanssa enempää.

Jos et jaksa odottaa ja et halua maksaa mahdollisia tulleja niin monista suomalaisista kaupoista saa myös. Triopak, radioduo, uraltone. Uraltonelle iso peukku nopeasta palvelusta. Nämä tietenkään eivät ole halvimpia, mutta jos lasket odottamiselle ja mahdollisille tulleille jonkun hinnan niin. Myös ebayn kautta saksasta saa noita. Hinnat halvempia kuin suomessa, mutta kalliimpia kuin kiinassa. Ei tulleja ja tulee reilussa viikossa. Esim tältä myyjältä tilasin itse juuri tuollaista tavaraa ja viikossa kolahti postiluukusta MAKERSHOP - We Love To Create. | eBay Stores
 
Onko joku este, että ei esim Aliexpress kelpaa? Monta myyjää, mutta yksi maksutapahtuma riittää.

Nakuttelet romut koriin ja kerralla maksu kuntoon.

Ei varsinaisesti, mutta ei ole kokemuksiakaan niin ajattelin että yhdestä ja samasta lafkasta tilaaminen olisi helpompaa ja turvallisempaa. Mutta ilmeisesti tuoltakin siis tulee ihan ok tavaraa.


Jos et jaksa odottaa ja et halua maksaa mahdollisia tulleja niin monista suomalaisista kaupoista saa myös. Triopak, radioduo, uraltone. Uraltonelle iso peukku nopeasta palvelusta. Nämä tietenkään eivät ole halvimpia, mutta jos lasket odottamiselle ja mahdollisille tulleille jonkun hinnan niin. Myös ebayn kautta saksasta saa noita. Hinnat halvempia kuin suomessa, mutta kalliimpia kuin kiinassa. Ei tulleja ja tulee reilussa viikossa. Esim tältä myyjältä tilasin itse juuri tuollaista tavaraa ja viikossa kolahti postiluukusta MAKERSHOP - We Love To Create. | eBay Stores


Kiitoksia, täytyy perehtyä tarkemmin.
 
Vielä pari vuotta sitten Aliexpressistä sai pirun halvalla täysin toimivat Arduinot, lisäosat ja Raspberry Pi:t, mutta nykyään jos tuotteen + toimitusmaksujen hinta ylittää 22€ se jää (EU:n ulkopuolelta tullessa) tulliin ja se on sitten ihan oma savottansa. Tullimaksut voi olla n. +30% ja jos ei osaa tai jaksa tullata itse niin tulli hoitaa tullauksen 20€ riistohintaan. Kaiken lisäksi tuotteet makaa tullissa helposti viikonkin kunnes tullin paperikirje tullauksen vaatimuksesta saapuu vastaanottajalle. Erittäin huono kokemus oli syksyllä kun tilasin Alista lentosimulaattoriin hotas-ohjaimen ja 60€ ostos paisui 90€ ja tuli vieläpä viikon myöhässä.

Ehdottomasti EU:n sisältä kannattaa tilata niinku tuossa jo muutkin ehdotti.
 
Onko porukalla suosituksia, mistä kiinalaisesta kaupasta arduinoja ja niihin liittyvää elektroniikkaa kannattaa tilata?
Sattuipa just kohilleen niin vastaan.
31.1.2021 tilasin Banggood -firmasta Kiinasta puoli tusinaa Unoa, pari Nanoa ja Megan sekä muuta rompetta (37 in 1-pussukan , näyttöjä, hyppylankoja, piirilevyjä ynnämuuta).
Kloonit olivat Geekcreit-brändimerkillä. Epämääräinen pussukka tömähti postista haettavaksi lauantaina 20.2 eli kolme viikkoa kesti toimitus.
Muutaman kerran muutaman vuoden aikana tuolta pikkujuttuja tilanneena en ole kokenut ongelmia, heillä on jopa jonkinasteinen seuranta tilaukselle.
Nyt tällä hetkellä taitaa olla päällä kiinalainen uusivuosi, joka viivyttänee toimituksia.
Ja alunperin oli tarkoitus tilata Euroopasta, mutta Banggoodin eurooppamyymälä ei suostunut toimittamaan tavaroita.
Laskeskelin, että tulleineen ja alveineen hinta jää silti soveliaaksi. Koska posti ei tehnyt tullausta, hoidan homman tietenkin netitse reippaana ja rehellisenä kansalaisena.
Epäilyttävästä (minimalistisesta) pakkaustyylistä huolimatta tavarat vaikuttivat ehjiltä, yhtä uunoa vasta olen ehtinyt kiusata ja se ainakin toimi.
Eli tämmöinen kokemus minulla.
 
Yhdyn näihin aliexpress vinkkeihin, mutta sen kyllä lisäisin että kannattaa ne hakutulokset laittaa järjestykseen ordersien ja/tai annettujen asiakasarvioiden (tähtien) perusteella. Näillä saa rajattua pois ne muutaman tilauksen myyjät pois. Ebay toimii myös ja sieltä myös suosiolla top-rated seller. Unoiksi kannattanee ottaa levy mikä on dip28 socketilla varustettu??
 
Aliexpressistä olen tilaillut vastuksia , konkkia ,BLE moduleita, IC:tä , fettejä, STM8S ja STM32 moduleita, jne ...
Yhtään viallista ei ole tullut esiin , aina on ollut syynä virheellinen analyysi oletetusta viasta.
Lithium akuissa on ollut muutama huonolaatuinen ja kapasiteetti mitä sattuu.
 
Terve! Tarvis vähän apuja tähän arduinosysteemiin, ite en tajua juuri mitään tästä. Elikkäs oon tehny diy käsijarrun tämän ohjeiden mukaan ja se toimii niinkuin pitää. Tuohon löyty siis valmis koodi mikä syötettii ohjelmaan.


Nyt rakentelin seq shifterin ja haluaisin sen toimiin tällä samalla pro microlla. Kolvasin mikrokytkimien maat samaan kuin potikankin. Pinneihin 5 ja 6 kytkimen toisen johdon. Sitten en tiedäkkään miten saada kaks painiketta ohjelmoitua tuohon, jotain youtube videoita oon koittanu kattoa mutta aattelin että jos joku tietävä osais tehdä/antaa neuvoa ettei tarvis opiskella koko laitteen filosofiaa. :lol:
Kiitokset jo etukäteen jos joku vaivautuu tsekkaan!

EDIT: Sain toimiin tämän ohjeella molemmat mutta käsijarrun akseli toimi väärin ja oli koko ajan päällä vaikka kalibroi. Sitten alkoi uus ongelma että tietokone ei enään tunnista laitetta lainkaan, voiko tuo kortti kärähtää vai mikä tuli?
 
Viimeksi muokattu:
Tuollaisella kytkennällä pinnit tulisi laittaa "INPUT_PULLUP". Tuolla joystick luokalla näyttäisi olevan setButton metodi, joka todennäköisesti olisi tarkoitukseen käypäinen. Ongelmalliseksi saattaa tulla nopeiden tuplaklikkausten händlääminen.

Joku tämän suuntainen saattaisi tehdä kaipaamasi asian. Tuollaisenaan ei välttämättä toimi (ainakaan hyvin), mutta jos siitä olisi apua alkuun pääsemisessä.
C++:
#include <Joystick.h>
int btn1_prevState = 0;
int btn2_prevState = 0;

void setup() {
  pinMode(A0, INPUT);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  Joystick.begin();
}

void loop() {
  int pot = analogRead(A0);
  int mapped = map(pot,0,1023,0,255);
  Joystick.setThrottle(mapped);

  int btn1 = !digitalRead(5);
  int btn2 = !digitalRead(6);

  if (btn1 != btn1_prevState) {
    Joystick.setButton(0, btn1);
    btn1_prevState = btn1;
  }

  if (btn2 != btn2_prevState) {
    Joystick.setButton(1, btn2);
    btn2_prevState = btn2; 
  }
}

Edit: githubista näköjään löytyy tuo joystick kirjasto ja jonkinnäköinen dokumentointi ja esimerkki: MHeironimus/ArduinoJoystickLibrary
 
Viimeksi muokattu:
Kiitokset vaan. Usb laitetta ei vaan enää tunnista joten taitaa olla meikäläisen turha koittaa samalle saada molempia toimintoja.. Täytyy tilata pari uutta arduinoa ja pitää laitteet ominaan, pääsee vähimmällä päänvaivalla. Tais tulla tiiliskivi tosta kortista.
 
Kiitokset vaan. Usb laitetta ei vaan enää tunnista joten taitaa olla meikäläisen turha koittaa samalle saada molempia toimintoja.. Täytyy tilata pari uutta arduinoa ja pitää laitteet ominaan, pääsee vähimmällä päänvaivalla. Tais tulla tiiliskivi tosta kortista.

Flashaat sen edellisen vaan takaisin :) Ei sen kortin pitäisi rikki mennä, ellei kytkennässä ole jotain vikaa.

Kannattaa lueskella tuolta githubista tuon joystick kirjaston dokumentaatiota tai googlailla esimerkkejä.
 
Katkoin kaikki johdot ja reset pin+maa koitin mutta ei auta, 3 punasta valoa palaa ja ei tunnista. Eli eiköhän se oo rikki.
 
Katkoin kaikki johdot ja reset pin+maa koitin mutta ei auta, 3 punasta valoa palaa ja ei tunnista. Eli eiköhän se oo rikki.
Koitappas pitää reset pohjassa, klikata upload ja laskea reset pois vasta kun ide sanoo "uploading" tmv. Noiden serialit käsittääkseni saattaa joskus jäädä johonkin perätilaan ja tuon pitäisi auttaa.
 
Näköjään sillä lähti pelaan, kerkesin jo tilata pari lisää kuitenkin. :rofl: Kiitokset avusta! Täytyy koittaa vielä roplata tota koodia ku nyt tietää miten saa nollattua.
 
Millä softilla täällä porukka vääntää arduinoo, meneehän se tuolla arduino idellä, mutta sillä ei näe rekisteriin ja virheentarkistus aika köppänen. Tärkein ehkä ois tuo virheentarkistus. Tarvis raapia päätä, jos ei toimi.

Suosituksia?

Mites visual studio ja siihen joku plugari, toimiiko? Ja saako kirjastoja ladattua edelleen suoraan?
PlatformIO on vscodelle ainakin ihan kiva. Voittaa arduino iden reippaasti ja jonkinlainen debuggerikin siitä löytyy. Tosin itse ei ole vähäisissä arduinohommissa tullut tuota debuggeria kokeiltua. Rekisterien kanssa leikkimisetkin on mennyt dokkareita lukemalla, yrittämällä ja erehtymällä.

Kannattaa tuota kuitenkin vilkaista, on ainakin yksi suosituimmista.
 
Millä softilla täällä porukka vääntää arduinoo, meneehän se tuolla arduino idellä, mutta sillä ei näe rekisteriin ja virheentarkistus aika köppänen. Tärkein ehkä ois tuo virheentarkistus. Tarvis raapia päätä, jos ei toimi.

Suosituksia?

Mites visual studio ja siihen joku plugari, toimiiko? Ja saako kirjastoja ladattua edelleen suoraan?

Visual studio + visual micro on ollut kätevä.
 
Tänään tuli Arduino Nano RP2040 Connect myyntiin, laitoin pari tilaukseen.

edit: 8 päivää kesti toimitus
nano_rp2040_connect.jpg
 
Viimeksi muokattu:
Elektroniikasta kun en juuri mitään ymmärrä, ni osaisko joku sanoa miksi moottorilähdöt menee pimeäksi yksi toisensa jälkeen?

Mulla simurigissä tuulisimu ja puhaltimia ohjataan siis Arduinolla.
Korttina tämä ja moottoriohjaimena tämä.
Puhaltimina nämä.

Tilasin nyt Arduinolta rev3 ohjaimen josko kestäisi paremmin, kait se sopii tuon mun kortin kanssa yhteen :hmm:

Virtaa tulee 12V / 2A erillisestä powerista.

Kortti on ABB:n jakorasiassa rattitason alla ilman kantta, mutta lämpö voi tietty olla ongelma.
Pitänee laittaa korotepalat väliin ja pohjaan reikiä.
 
Elektroniikasta kun en juuri mitään ymmärrä, ni osaisko joku sanoa miksi moottorilähdöt menee pimeäksi yksi toisensa jälkeen?

Mulla simurigissä tuulisimu ja puhaltimia ohjataan siis Arduinolla.
Korttina tämä ja moottoriohjaimena tämä.
Puhaltimina nämä.

Tilasin nyt Arduinolta rev3 ohjaimen josko kestäisi paremmin, kait se sopii tuon mun kortin kanssa yhteen :hmm:

Virtaa tulee 12V / 2A erillisestä powerista.

Kortti on ABB:n jakorasiassa rattitason alla ilman kantta, mutta lämpö voi tietty olla ongelma.
Pitänee laittaa korotepalat väliin ja pohjaan reikiä.

Ohjainkortti sanoo 0.6A jatkuvaa, 1.2A hetkellisesti.
Puhallin 12V 10.1W = ~0.8A eli ohjain on liian pieni tuolle puhaltimelle ja siksi ohjainpiiri palaa pidemmässä käytössä.

Tuo rev3 käyttää eri ohjainta ja kestää 2A jatkuvaa, sen pitäisi kestää.
 

Statistiikka

Viestiketjuista
262 582
Viestejä
4 558 817
Jäsenet
75 004
Uusin jäsen
otso.lan

Hinta.fi

Back
Ylös Bottom