Wenn du damit die Hardware Treiber Module meinst, nein. Die haben keine Variablen, merken sich nichts. Beim enablen/disablen kann es höchtens einen Ruckler um +- 1/2 Schritt geben, also so rund um 1° Drehung.
Es ist ein Software Problem.
MfG Klebwax
Druckbare Version
Ich versuche mal ein wenig Licht in die Sache zu bringen. Da sind mir noch mehr Dinge aufgefallen, die ich nicht so recht in dem Code von Inka verstehe. Wie das Verwenden von runSpeed(). Das soll immer wieder aufgerufen werden (?), damit der Motor seine Schritte tut, allerdings ruft Inka danach immer wieder die move()-Methode auf? Die Verwendung von move(), setSpeed() usw. verstehe ich noch nicht so recht.
Aber zunächst mal was anderes:
die Klassenreferenz: http://www.airspayce.com/mikem/ardui...elStepper.html
zu: stepper_VL, stepper_HL, stepper_VR, stepper_HR, stepper_MAX
habe ich keine Werte gefunden, welche verbergen sich dahinter?
Übersetzung:
Sie können mehrere gleichzeitige Stepper verwenden, die sich alle mit unterschiedlichen Geschwindigkeiten und Beschleunigungen bewegen,
vorausgesetzt, Sie rufen ihre run () - Funktionen in ausreichend regelmäßigen Abständen auf.
Die aktuelle Position ist auf 0 und die Zielposition auf 0 eingestellt. Die Standardeinstellung für MaxSpeed und Acceleration ist 1.0.
Die Motorpins werden während des Konstruktors durch einen Aufruf von enableOutputs () in den OUTPUT-Modus initialisiert.
setEnablePin()
--------------
Legt die Aktivierungs-PIN-Nummer für Schritttreiber fest. 0xFF zeigt unbenutzt an (Standard). Andernfalls, wenn ein Pin gesetzt ist,
wird der Pin beim Aufruf von enableOutputs () eingeschaltet und beim Aufruf von disableOutputs () ausgeschaltet.
Der Ordnung halber würde ich den Enable-Pin über diese Methode, für alle 4988, festlegen. Auch wenn es, zumindest scheinbar, an
der LIB vorbei funktioniert.
stop()
------
Der Stepper soll unter Verwendung der aktuellen Geschwindigkeits- und
Beschleunigungsparameter so schnell wie möglich anhalten.
disableOutputs()
----------------
Deaktivieren Sie die Motor-Pin-Ausgänge, indem Sie alle auf LOW stellen. Abhängig vom Design Ihrer Elektronik kann dies
die Stromversorgung der Motorspulen unterbrechen, um Strom zu sparen. Dies ist nützlich, um Arduino-Energiesparmodi
zu unterstützen: Deaktivieren Sie die Ausgänge für den Ruhezustand und aktivieren Sie sie dann erneut mit enableOutputs(),
bevor Sie erneut einen Schritt ausführen. Wenn der Aktivierungs-Pin definiert ist, wird er in den OUTPUT-Modus
versetzt und der Pin auf deaktiviert gesetzt.
isRunning()
-----------
Überprüft, ob der Motor gerade läuft.
Hier habe ich Zweifel, wegen dem UND-Operator.
"1" und "0" ergibt normalerweise "0".Code:/***********************************************************/
boolean fahrt_fertig()
{
return stepper[stepper_VL].isRunning() && stepper[stepper_HL].isRunning() && stepper[stepper_VR].isRunning()
&& stepper[stepper_HR].isRunning();
}
fahrt_fertig() gäbe FALSE, wenn nur 1 Motor nicht mehr läuft.
Wenn alle Ergebnisse von isRunning() zusammengeführt werden
sollen, würde ich das ändern in folgenden Code, mit dem ODER-Operator.
Dann gäbe fahrt_fertig() ein FALSE, wenn alle Motoren nicht mehr laufen.Code:/***********************************************************/
boolean fahrt_fertig()
{
return stepper[stepper_VL].isRunning() || stepper[stepper_HL].isRunning() || stepper[stepper_VR].isRunning()
|| stepper[stepper_HR].isRunning();
}
Folgender Code, um die Stepper anzuhalten.
Code:/***********************************************************/
void alle_stepper_stop(void)
{
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].stop();
stepper[idx].disableOutputs();
}
/*
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
reboot();
*/
}
stop() soll den Motor - so schnell wie möglich - anhalten.
disableOutputs() sollte den a4988 Motortreiber abschalten,
so dass der Motor sofort anhalten sollte.
Normalerweise erst stoppen, dann abschalten.
Später dann wieder anschalten enableOutputs() und den Motor bewegen.
MfG
- - - Aktualisiert - - -
Auch mal bitte prüfen, ob der Code der Fernbedienung ohne Verzögerung im Programm ankommt, ob von dort irgendwo die Verzögerung (vorwärts auf rückwärts) herrührt.
- - - Aktualisiert - - -
Beispiel:
stepper[index].setEnablePin(Pinnummer);
siehe auch: setPinsInverted()
stepper[index].setPinsInverted(false,false,true); //weil der Enable ein invertierender Eingang ist
ich gebe ja zu, das ganze basiert auf anderen steppern und treibern (siehe anhang), auf einer anderen LIB (CustomStepper) und auf meiner naivität das ganze irgendwie auf die neue situation "anzupassen"...
diese bezeichnungen beziehen sich auf die vier stepper (V_orne L_inks usw.) und im zusammenhang mit der variablen "idx" sollen diese in der schleife:Zitat:
zu: stepper_VL, stepper_HL, stepper_VR, stepper_HR, stepper_MAX
habe ich keine Werte gefunden, welche verbergen sich dahinter?
alle vier gleichzeitig in bewegung gesetzt werden, ohne diese schleife liefen die früher nacheinander an...Code:for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].run();
// delay(1);
}
Ich versuch jetzt mal das ganze mit direkten anweisungen an die DIR und STEP pins der stepper zu realisieren, ohne LIB :-)
so, dieser
kommt ohne eine stepper-lib aus, funktioniert soweit...Code:
//libraries
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#include <IRremote.h>
#include <Bounce2.h>
uint8_t RECV_PIN = 13;
uint8_t taste = 0;
uint8_t zaehler = 1;
//resett pin definieren
#define PIN2RESET 10
// DIR und STEP pins definieren
#define dirPin_VL 2
#define stepPin_VL 3
#define dirPin_HL 4
#define stepPin_HL 5
#define dirPin_VR 6
#define stepPin_VR 7
#define dirPin_HR 8
#define stepPin_HR 9
//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43
//definiere steps pro umdrehung:
#define stepsPerRevolution 200
//IR pin definieren
IRrecv irrecv(RECV_PIN);
decode_results results;
// debouncer instanz definieren
Bounce debouncer = Bounce();
void setup()
{
// deklariere pins als output:
pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);
Serial.begin(115200);
Serial.println("code----/home/georg/Arduino/outdoor_robo/stepper/test_vier_stepper/ohne_lib/remote_vier_stepper_switch_1_enbl_bounce");
//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);
// IR empfänger pin mit bounce verbinden
debouncer.attach(RECV_PIN);
// debounce interval in ms
debouncer.interval(5);
// starte IR receiver
irrecv.enableIRIn();
// deaktiviere enable pins:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}
void loop()
{
// aktiviere enable pins:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
// Update the Bounce instance :
debouncer.update();
// Get the updated value :
zaehler = debouncer.read();
if (zaehler == 1)
{
zaehler = 0;
// taste = 0;
if (irrecv.decode(&results))
{
taste = results.value;
Serial.println(taste);
// delay(1000);
irrecv.resume(); // Receive the next value
}
}
tasten_abfrage();
}
/***********************************************************/
void tasten_abfrage(void)
{
switch (taste)
{
case 151 ://taste 1 große FB
{
if (taste == 151 )
{
Serial.println("szenario_1");
Serial1.println("szenario_1");
//fahre szenario_1
delay (1000);
break;
}
}
case 103://taste 2 große FB
{
if (taste == 103)
{
Serial.println("szenario_2");
Serial1.println("szenario_2");
//fahre szenario_2
delay (1000);
break;
}
}
case 79://taste 3 große FB
{
if (taste == 79)
{
Serial.println("szenario_3");
Serial1.println("szenario_3");
//fahre szenario_3
delay (1000);
break;
}
}
case 207://taste 4 große FB
{
if (taste == 207)
{
Serial.println("szenario_4");
Serial1.println("szenario_4");
//fahre szenario_4
delay (1000);
break;
}
}
case 253://OK taste, motor stop
{
if (taste == 253)
{
alle_stepper_stop();
break;
}
}
case 61:// rotate rechts große FB
{
if (taste == 61)
{
rechts_drehen();
break;
}
}
case 221:// rotate links große FB
{
if (taste == 221)
{
links_drehen();
break;
}
}
case 157:// fahre vor große FB
{
if (taste == 157)
{
vorwaerts();
break;
}
}
case 87:// fahre rückwärts große FB
{
if (taste == 87)
{
rueckwaerts();
break;
}
}
}
}
/***********************************************************/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
reboot();
}
/***********************************************************/
void vorwaerts(void)
{
// aktiviere enable pins:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);
for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(2000);
}
}
/**********************************************************/
void rueckwaerts(void)
{
// aktiviere enable pins:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);
for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(2000);
}
}
/***********************************************************/
void rechts_drehen(void)
{
// enable pins aktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);
for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(2000);
}
}
/**********************************************************/
void links_drehen(void)
{
//enable pins aktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);
for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(2000);
}
}
/***********************************************************/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/***********************************************************/
/************************************************************/
die erweiterungen / aufnahmen für die A4988 sowie der stärkere akku sind noch unterwegs, erst dann, mit der notwendigen einstellung der ströme zu den steppern kann ich sagen wie es weitergeht...
wieder eine kleinigkeit:
Anhang 34473
Anhang 34474
Anhang 34475
ich hoffe - auch wenn ich noch gar nicht weiss, ob das ding auch wirklich was wird - es damit etwas "outdoortauglicher" gemacht zu haben. Das ausdenken, entwerfen, drucken und montieren hat riesig spass gemacht...
Bei mir ist oft der weg das ziel :-)
Geht mir immer genauso....dir kommt eine Idee.
Die reift einige Tage im Kopf, und dann setzt du dich an Blender (oder halt das bevorzugte CAD-Programm), und die Idee reift weiter, nimmt virtuell Form an.
Tage später (oder Stunden, oder Wochen) liegt die Idee fertig vor dir.
Ich liebe den 3D-Drucker.:)
Und mir gehts genauso: der Werdegang ist oft sogar spannender als das eigentliche Endergebnis....
Inka, ich kann es zwar ahnen, was Du da gedruckt hast, aber bin mir nicht sicher, ob es das ist, was ich denke. Schreib doch einfach dabei, was es ist! Hmmm, sieht so aus, asl ob ein Bild seitenverkehrt ist. Kann das sein?
Hat riesig Spaß gemacht .. der Weg ist das Ziel. Bist Du schon am Ende? - Hoffentlich nicht! ;)
MfG
es ist eine kappe für die vier leitungen zum schrittmotor - damit die nicht so schutzlos im freien herumhängen. Und seitenverkehrt nur insofern, dass auf dem linken rad die kappe schon drauf war, am rechten noch nicht. Oder umgekehrt... :-)
Und am ende bin ich noch lange nicht, ich wollte mir das warten auf teile etwas verkürzen... ;-)
btw (wir haben ja kein unterforum): Bei meinem 3D drucker ist der platz für die filamentspule etwas begrenzt. Hat schon jemand filament von einer grossen (1kg) auf eine kleinere (0,5kg) spule umgewickelt? Geht das überhaupt vernünftig?
Dann sollten wir das jetzt so machen, dass wir die 3D-Drucker-Sachen unter Konstruktion/CAD rein stellen: https://www.roboternetz.de/community...e-Fritzing-u-a
Vielleicht einen Thread mit dem Thema: 3D-Drucker - Hilfe/Probleme/Suche
Dort kann jeder sich dranhängen, wenn es um die Hardware von 3D-Druckern geht. Noch sind es nicht so viele, die dort was schreiben würden, denke ich, vielleicht wird später ein Unterforum draus.
Und vielleicht einen Thread mit dem Thema: 3D-Druck CAD/Slicer
Dort kann jeder sich dranhängen, wenn es dazu Fragen gibt.
Zuerst aber:
Umwickeln kannst Du das, wenn Du willst. Geht das venünftig? - Nein. Dabei wird später das Abwickeln etwas erschwert, dennoch funktioniert das trotzdem. Jedenfalls bei meinem Drucker bisher immer. Habe schon Filamentspulen gekauft, wo ein Rest aufgewickelt war, da ist das dann auch nicht anders, dass sich die Wicklungen hinterher etwas verheddern, durch Überkreuzen - liegt am Material.
Wer jetzt aufmerksam ist, wird bemerken (so wie ich jetzt gerade) dass 3D-Druck automatisch verlinkt wird, auf eine weitere Seite von Frank, unserm Forenbetreiber hier. Dort hat er wohl auch was für 3D-Drucker übrig (habe da noch nicht genau geschaut). Vielleicht hat er sich das dann jetzt so gedacht!?
MfG
Du müsstest dir ne simple Vorrichtung bauen:
die Spender-Rolle sollte leicht gebremst werden (gerade PLA verhält sich wie ne Feder, das wickelt sich alleine teilweise ab), und die Empfänger-Rolle solltest du manuell oder auch elektrisch drehen. Wichtig ist, dass dein Filament immer _leicht_ unter Spannung steht, dann müsste das sich auch gut aufwickeln.
Entgegen der landläufigen Meinung ist es nämlich Wurst, wie "ordentlich" ein Fliament aufgewickelt ist- meine sind oft gar nicht so toll aufgewickelt.
Interessiert den Drucker überhaupt nicht.
Nur Knoten darf es natürlich nicht geben.
Manche Filamente neigen übrigens zum brechen, wenn sie auf zu dünne Durchmesser aufgerollt werden.....
hat gut geklappt:
Anhang 34476
ein drehteller (ich glaub von fondue), 10 minuten drehen und das wars...
Um ein video aufzunehmen hat die dritte hand gefehlt...
Ich habe es schon mit der Drehbank umgespult. Hatte das Problem das eine Dickstelle im Filament war und ich den Druck nach über 40h abbrechen musste. Damit das nicht mehr passiert habe ich das Filament kontrolliert. Habe mir aber einen Sensor gebaut der das registrieren soll. Muss ich aber noch testen und optimieren.
MfG Hannes
Mit wieviel Spannung muß das aufgewickelt werden?
MfG
Das Material darf nicht locker sein, das ist die Hauptsache.
Was auch noch wichtig ist, ist das du keine Stelle hast mit einem "Berg" oder einem "Tal". Wenn das passiert kann es das Material beim Verarbeiten nachrutschen und sich das Material verzwicken.
MfG Hannes
Anhang 34477
habe nicht so drauf geachtet, habe einfach mit der rechten hand gedreht, mit der linken die grosse spule etwas gebremst, also das filament ein bischen unter spannung gehalten und versucht das material auf der kleineren spule ein bischen zu verteilen. Besonders ist es nicht gelungen, der drucker druckt aber...
p.s. werden hier neuerdings alle fotos in "landscape" gedreht?
hallo allerseits,
die adapterplatinen für die motortreiber A4988 sind nun endlich gekommen, eingebaut und das ganze funktioniert auch...
Die adapter haben auch die möglichkeit, die steppermotoren was die schrittweite betrifft (1 / 0.5, 0.25......) einzustellen und auch die potis auf den motortreibern sind gut zugänglich....
Ich weiss, dass man die einstellung der treiber/stepper mit einstellung der spannung zwischen masse und dem poti machen kann, habe aber auch schon gelesen, dass man den punkt, an dem die stepper stehen bleiben suchen kann und dann den punkt wählen kann, wo sie "geradeso" laufen...
Diese möglichkeit ist aber wahrscheinlich aus der ecke "3D-drucker" gekommen und dort auch gerechtfertigt, man braucht nicht unbedingt grosses drehmoment dort...
Alles, was bei der poti einstellung über diesen punkt hinausgeht, steigert das drehmoment, den strom, den die stepper ziehen, aber auch die temperatur. Die frage, die mich nun beschäftigt ist, wie warm dürfen die stepper bzw. die kühlkörper werden? Im netz findet man aussagen - 70° ist gut, 100°C ist eher zu viel....
Gibt es andere erfahrungswerte?
Die Motoren dürfen, unter Last, deutlich warm werden. Schätzungsweise ~50°C. Wenn Du sie mit der Hand nicht mehr anfassen kannst, ist es zu viel. 100°C wären viel zu viel - nicht gut.
Die Kühlkörper geben sehr viel Wärme ab, wenn die Motoren richtig arbeiten müssen. Auch etwa 50 bis 60°C. Aber: die 4988 haben einen Schutz, werden sie zu heiß, sollten sie abschalten.
MfG
ein versuch mit steigung hab ich gemacht: https://youtu.be/zeQfXrpw3DI
steigungsweinkel ca 9°, keinerlei probleme...
steigungswinkel verdoppelt, also ca. 18°, die stepper laufen bei beiden versuchen im halbschritt und mit einer verzögerung von 2ms zwischen HIGH und LOW...
https://youtu.be/nPnKT4-R_8o
es ist aber bei weitem nicht so aufregend, wie der "klatschi" vom Rumgucker, bei mir ist es egal, ob eine oma, ein auto oder ein hund vor die karre laufen, die kommen alle noch rechtzeitig weg :-)
Bei dem wackligen aufbau traue ich mich aber nicht die geschwindigkeit zu erhöhen, weil mir das dann vermutlich alles um die ohren fliegt...
korrektur:
---------------------------------------------------------------------------------
bei einer steigung von ca. 20°, im halbschritt und einem delay zwischen HIGH und LOW von 0.5ms, schafft er es auch und deutlich schneller:
https://youtu.be/t8sk6ldp5fI
Musst jetzt nur aufpassen, bei den Microschritten verlierst Du Drehmoment. Immer im Hinterkopf behalten.
MfG
diesmal ohne video dafür mit dem letzten
der letzter stand ist: halbschritt und 2,5ms zwischen HIGH und LOW, damit fährt er 1m in ca 2sekunden. Das reicht erstmal, würde ich sagen. Damit schafft er auch eine 20° steigung, mehr konnte ich innen nicht testen und mehr haben wir hier kaum an der Elbe:-), ausser in der Sächsischen Schweiz, und da ist es dann doch zu steil und sandig...Code:
//libraries
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#include <IRremote.h>
#include <Bounce2.h>
uint8_t RECV_PIN = 13;
uint8_t taste = 0;
uint8_t zaehler = 1;
//resett pin definieren
#define PIN2RESET 10
// DIR und STEP pins definieren
#define dirPin_VL 2
#define stepPin_VL 3
#define dirPin_HL 4
#define stepPin_HL 5
#define dirPin_VR 6
#define stepPin_VR 7
#define dirPin_HR 8
#define stepPin_HR 9
//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43
//steps pro umdrehung definieren:
#define stepsPerRevolution 200
//IR pin definieren
IRrecv irrecv(RECV_PIN);
decode_results results;
// debouncer instanz definieren
Bounce debouncer = Bounce();
void setup()
{
//pins als output:
pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);
Serial.begin(115200);
//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);
// IR empfänger pin mit bounce verbinden
debouncer.attach(RECV_PIN);
// debounce interval in ms
debouncer.interval(5);
// starte IR receiver
irrecv.enableIRIn();
//enable pins deaktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}
void loop()
{
/*
// aktiviere enable pins:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
*/
// bounce instance updaten:
debouncer.update();
// neuen bounce wert holen :
zaehler = debouncer.read();
if (zaehler == 1)
{
zaehler = 0;
// taste = 0;
if (irrecv.decode(&results))
{
taste = results.value;
Serial.println(taste);
// delay(1000);
// nächsten IR-wert empfangen
irrecv.resume();
}
}
tasten_abfrage();
}
/***********************************************************/
void tasten_abfrage(void)
{
switch (taste)
{
case 151 ://taste 1 große FB
{
if (taste == 151 )
{
Serial.println("szenario_1");
Serial1.println("szenario_1");
//fahre szenario_1
delay (1000);
break;
}
}
case 103://taste 2 große FB
{
if (taste == 103)
{
Serial.println("szenario_2");
Serial1.println("szenario_2");
//fahre szenario_2
delay (1000);
break;
}
}
case 79://taste 3 große FB
{
if (taste == 79)
{
Serial.println("szenario_3");
Serial1.println("szenario_3");
//fahre szenario_3
delay (1000);
break;
}
}
case 207://taste 4 große FB
{
if (taste == 207)
{
Serial.println("szenario_4");
Serial1.println("szenario_4");
//fahre szenario_4
delay (1000);
break;
}
}
case 253://OK taste, motor stop
{
if (taste == 253)
{
alle_stepper_stop();
break;
}
}
case 61:// rotate rechts große FB
{
if (taste == 61)
{
rechts_drehen();
break;
}
}
case 221:// rotate links große FB
{
if (taste == 221)
{
links_drehen();
break;
}
}
case 157:// fahre vor große FB
{
if (taste == 157)
{
vorwaerts();
break;
}
}
case 87:// fahre rückwärts große FB
{
if (taste == 87)
{
rueckwaerts();
break;
}
}
}
}
/***********************************************************/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
reboot();
}
/***********************************************************/
void vorwaerts(void)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);
for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(250);
}
}
/**********************************************************/
void rueckwaerts(void)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);
for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}
/***********************************************************/
void rechts_drehen(void)
{
// enable pins aktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);
for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}
/**********************************************************/
void links_drehen(void)
{
//enable pins aktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);
for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}
/***********************************************************/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/***********************************************************/
/************************************************************/
Ich werde jetzt ein paar "szenarios" einprogrammieren und bei schönerem wetter ein paar bilder vom outdooreinsatz schicken....
Die bedienung ist erstmal mit IR, das geht draussen natürlich nur schlecht. Der nächste schritt ist WiFi, sprich der ESP32 kommt zusätzlich rein, die komunikation über I2C mit dem 2560 als motorsteuerung muss noch entwickelt werden und die bedienung über WiFi über smartphone geschrieben werden....
Dieser
sollte umgeschrieben werde, war ursprünglich für die autonome TT - lok geschrieben, bzw. abgewandelt worden...Code:// https://microcontrollerslab.com/esp32-web-server-arduino-led/#Displaying_HTML_web_server_with_ESP32
#include <Arduino.h>
#include <analogWrite.h>
#include <WiFi.h>
#include <WebServer.h>
double velo = 0;
const char* ssid = "ESP32-lok"; //PTCL-BB
const char* password = "12345678"; //5387c614
WiFiServer server(80);
String header;
String LED_ONE_STATE = "vorwaerts";
String LED_TWO_STATE = "aus";
String LED_THREE_STATE = " 0 ";
String LED_FOUR_STATE = "aus";
//String MOTOR_STATE = "off";
//String DIRECTION_STATE = "off";
const int GPIO_PIN_NUMBER_5 = 5;
const int GPIO_PIN_NUMBER_18 = 18;
const int GPIO_PIN_NUMBER_22 = 22;
const int GPIO_PIN_NUMBER_19 = 19;
//const int GPIO_PIN_NUMBER_9 = 9; //motor
//const int GPIO_PIN_NUMBER_10 = 10;//direction
IPAddress local_ip(192, 168, 1, 101);
IPAddress gateway(192, 168, 1, 101);
IPAddress subnet(255, 255, 255, 0);
void setup() {
Serial.begin(115200);
Serial.print("code----ESP_32/pico_lok/HTTP_AP_server_motor_control_8_buttons_velo");
pinMode(GPIO_PIN_NUMBER_5, OUTPUT);
pinMode(GPIO_PIN_NUMBER_18, OUTPUT);
pinMode(GPIO_PIN_NUMBER_22, OUTPUT);
pinMode(GPIO_PIN_NUMBER_19, OUTPUT);
// pinMode(GPIO_PIN_NUMBER_9, OUTPUT);
// pinMode(GPIO_PIN_NUMBER_10, OUTPUT);
digitalWrite(GPIO_PIN_NUMBER_5, LOW);
digitalWrite(GPIO_PIN_NUMBER_18, LOW);
digitalWrite(GPIO_PIN_NUMBER_22, LOW);
digitalWrite(GPIO_PIN_NUMBER_19, LOW);
// digitalWrite(GPIO_PIN_NUMBER_9, LOW);
// digitalWrite(GPIO_PIN_NUMBER_10, LOW);
Serial.print("Connecting to ");
Serial.println(ssid);
// WiFi.begin(WIFI_NAME, WIFI_PASSWORD);
WiFi.softAP(ssid, password);
WiFi.softAPConfig(local_ip, gateway, subnet);
/*
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
Serial.println("Trying to connect to Wifi Network");
}
*/
Serial.println("");
Serial.println("Successfully connected to WiFi network");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
}
void loop() {
WiFiClient client = server.available();
if (client)
{
Serial.println("New Client is requesting web page");
String current_data_line = "";
while (client.connected())
{
if (client.available())
{
char new_byte = client.read();
Serial.write(new_byte);
header += new_byte;
if (new_byte == '\n')
{
if (current_data_line.length() == 0)
{
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// lok vorwärts/rückwärts
if (header.indexOf("LED1=ON") != -1)
{
Serial.println("GPIO5 LED is ON");
LED_ONE_STATE = "vorwaerts";
digitalWrite(GPIO_PIN_NUMBER_5, HIGH);
}
if (header.indexOf("LED1=OFF") != -1)
{
Serial.println("GPIO5 LED is OFF");
LED_ONE_STATE = "rueckwaerts";
digitalWrite(GPIO_PIN_NUMBER_5, LOW);
}
// lok an/aus
if (header.indexOf("LED2=ON") != -1)
{
Serial.println("GPIO18 LED is ON");
LED_TWO_STATE = "an";
analogWrite(GPIO_PIN_NUMBER_18, velo); //HIGH);
}
if (header.indexOf("LED2=OFF") != -1)
{
Serial.println("GPIO18 LED is OFF");
LED_TWO_STATE = "aus";
analogWrite(GPIO_PIN_NUMBER_18, LOW);
}
//lok schneller/langsammer
if (header.indexOf("LED3=ON") != -1)
{
Serial.println("GPIO22 LED is ON");
velo = velo + 5;
LED_THREE_STATE = velo; //"on";
//analogWrite(GPIO_PIN_NUMBER_22, velo);//HIGH
}
if (header.indexOf("LED3=OFF") != -1)
{
Serial.println("GPIO22 LED is OFF");
velo = velo - 5;
LED_THREE_STATE = velo; //"off";
//analogWrite(GPIO_PIN_NUMBER_22, velo); //LOW
}
if (header.indexOf("LED4=ON") != -1)
{
Serial.println("GPIO19 LED is ON");
LED_FOUR_STATE = "an";
digitalWrite(GPIO_PIN_NUMBER_19, HIGH);
}
if (header.indexOf("LED4=OFF") != -1)
{
Serial.println("GPIO19 LED is OFF");
LED_FOUR_STATE = "aus";
digitalWrite(GPIO_PIN_NUMBER_19, LOW);
}
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: 2px solid #4CAF50;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 1px 1px; cursor: pointer; }");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
// Web Page Heading
client.println("</style></head>");
//client.println("<body><center><h1>ESP32 Web server LED controlling example</h1></center>");
//client.println("<center><h2>Web Server Example Microcontrollerslab.com</h2></center>" );
//client.println("<center><h2>Press on button to turn on led and off button to turn off LED</h3></center>");
client.println("<form><center>");
client.println("<p> richtung ist " + LED_ONE_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED1\" value=\"ON\" type=\"submit\">VORW</button>") ;
client.println("<button class=\"button\" name=\"LED1\" value=\"OFF\" type=\"submit\">RUECKW</button></center>");
client.println("<p>motor ist " + LED_TWO_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED2\" value=\"ON\" type=\"submit\">AN</button>");
client.println("<button class=\"button\" name=\"LED2\" value=\"OFF\" type=\"submit\">AUS</button></center>");
client.println("<p>geschwindigkeit ist " + LED_THREE_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED3\" value=\"ON\" type=\"submit\">SCHNELLER</button>");
client.println("<button class=\"button\" name=\"LED3\" value=\"OFF\" type=\"submit\">LANGSAMMER</button></center>");
client.println("<p>kamera ist " + LED_FOUR_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED4\" value=\"ON\" type=\"submit\">AN</button>");
client.println("<button class=\"button\" name=\"LED4\" value=\"OFF\" type=\"submit\">AUS</button></center>");
client.println("</center></form></body></html>");
client.println();
break;
}
else
{
current_data_line = "";
}
}
else if (new_byte != '\r')
{
current_data_line += new_byte;
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
vielleicht greife ich hier zu weit vor, aber warum eigentlich nicht. Der Mega 2560 soll ja als "motorbetreuer" dienen, evtl. bekommt er noch ein paar sensoren zur seite...
Für die kommunikation nach aussen (und innen) soll ein LOLIN ESP32 dienen, den hatte ich als "rest" aus dem projekt der autonomen TT-lok noch da. Das menü auf dem smartphone sah dort so aus:
Anhang 34490
dies soll, da die bedienung des outdoor roboters ja viel umfangreicher sein wird durch so etwas
Anhang 34491
ersetzt werden...
Die übernahme des AP-servers macht mir denke ich keine probleme, wie ich aber die (html?) programmierung des neuen bedienfeldes hinbekommen soll, da habe ich keinen blassen schimmer... Wer hilft?
Wenn Du Hilfe beim HTML-Bedienfeld brauchst, kann ich das gerne für Dich übernehmen. Allerdings habe ich keinen ESP32, nur ein ESP-12E. Müsstest den Code dann auf dem ESP32 selbst zum Laufen bringen, wenn Du nicht ganz unbewandert bist, sollte das funktionieren.
Gruß
also bitte nicht übernehmen, das war nicht der hintergrund meiner frage nach hilfe - ich möchte schliesslich verstehen, was da in dem code passiert... :-)
Die situation:
- auf dem ESP läuft ein webserver, der ist an sich kein problem, zumindest habe ich (halbwegs) verstanden was da abläuft...
- der webserver soll auf "tastendrücke" am smartphone reagieren und die werte, die jetzt die IR-fernbedienung (weiss nicht ob das so sinnvoll ist?) vom ESP über I2c an den arduino liefern...
- evtl. die IR fernbedienung nur um die werte, die jetzt vom smartphone kommen ergänzen, sodass beide bedienungen funktionieren?
- der arduino soll per switch() - wie jetzt auch schon - die vom ESP kommenden befehle umsetzen und die motoren steuern...
Die beiden sketches, so wie sie jetzt sind (die am arduino funktioniert ja bereits mit der IR fernbedienung) und die basis für den webserver (die ich teilweise übernehmen wollte) sind im vorletzten post enthalten. Meinst Du wir können so erstmal starten?
Dann habe ich das in der Kürze Deiner Anfrage nicht vollständig verstanden, wie Du das jetzt weiter beschreibst.
Aber dennoch: das Tastenfeld der abgebildeten Fernbedienung kannst Du in eine HTML-Seite packen, die kannst Du per Webbrowser von jedem Gerät, dass einen hat, aufrufen.
Als zweites hast Du dann noch die Fernbedienung zum in die Hand nehmen, die ja sowieso schon funktioniert, wie Du sagst.
Das halte ich für am einfachsten, für jeden.
Dies habe ich noch nicht verstanden:
Zitat:
evtl. die IR fernbedienung nur um die werte, die jetzt vom smartphone kommen ergänzen, sodass beide bedienungen funktionieren?
MfG
- - - Aktualisiert - - -
Du kannst Deinen alten Code natürlich umstricken. Dann musst Du sagen, wobei Du genau Hilfe brauchst. Beim Quelltext für HTML? Oder noch was anderes?
MfG
- - - Aktualisiert - - -
Das Bild von der Fernbedienung: kannst Du mal eine ganz genaue Aufnahme direkt von oben machen? Dann kann das Bild bearbeitet werden, dass es sich möglichst gut komprimieren lässt und dann könnte das als Hintergrundbild verwendet werden. Darüber wird ein Raster mit Elementen gelegt, die beim Anklicken die Stelle hervorheben, die auf dem Bild angeklickt wurde. Wäre eine Möglichkeit die Bedienung in HTML bedienbar zu machen.
das ist genau der punkt, wo ich hilfe bräuchte... vielleicht sollten wir uns erstmal auf den aufbau der webseite konzentrieren. Ich hab ja vor jahrzenten bereits ein bischen was mit HTML, PHP und CSS gemacht, aber das ist einerseits sicher überholt und auch bereits so gut wie vergessen. Ein paar begriffe und ihre bedeutung sind noch da, mehr ist es aber nicht...
das hier
ist das problem,Code:while (client.connected())
{
if (client.available())
{
char new_byte = client.read();
Serial.write(new_byte);
header += new_byte;
if (new_byte == '\n')
{
if (current_data_line.length() == 0)
{
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// lok vorwärts/rückwärts
if (header.indexOf("LED1=ON") != -1)
{
Serial.println("GPIO5 LED is ON");
LED_ONE_STATE = "vorwaerts";
digitalWrite(GPIO_PIN_NUMBER_5, HIGH);
}
if (header.indexOf("LED1=OFF") != -1)
{
Serial.println("GPIO5 LED is OFF");
LED_ONE_STATE = "rueckwaerts";
digitalWrite(GPIO_PIN_NUMBER_5, LOW);
}
// lok an/aus
if (header.indexOf("LED2=ON") != -1)
{
Serial.println("GPIO18 LED is ON");
LED_TWO_STATE = "an";
analogWrite(GPIO_PIN_NUMBER_18, velo); //HIGH);
}
if (header.indexOf("LED2=OFF") != -1)
{
Serial.println("GPIO18 LED is OFF");
LED_TWO_STATE = "aus";
analogWrite(GPIO_PIN_NUMBER_18, LOW);
}
//lok schneller/langsammer
if (header.indexOf("LED3=ON") != -1)
{
Serial.println("GPIO22 LED is ON");
velo = velo + 5;
LED_THREE_STATE = velo; //"on";
//analogWrite(GPIO_PIN_NUMBER_22, velo);//HIGH
}
if (header.indexOf("LED3=OFF") != -1)
{
Serial.println("GPIO22 LED is OFF");
velo = velo - 5;
LED_THREE_STATE = velo; //"off";
//analogWrite(GPIO_PIN_NUMBER_22, velo); //LOW
}
if (header.indexOf("LED4=ON") != -1)
{
Serial.println("GPIO19 LED is ON");
LED_FOUR_STATE = "an";
digitalWrite(GPIO_PIN_NUMBER_19, HIGH);
}
if (header.indexOf("LED4=OFF") != -1)
{
Serial.println("GPIO19 LED is OFF");
LED_FOUR_STATE = "aus";
digitalWrite(GPIO_PIN_NUMBER_19, LOW);
}
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: 2px solid #4CAF50;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 1px 1px; cursor: pointer; }");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
// Web Page Heading
client.println("</style></head>");
//client.println("<body><center><h1>ESP32 Web server LED controlling example</h1></center>");
//client.println("<center><h2>Web Server Example Microcontrollerslab.com</h2></center>" );
//client.println("<center><h2>Press on button to turn on led and off button to turn off LED</h3></center>");
client.println("<form><center>");
client.println("<p> richtung ist " + LED_ONE_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED1\" value=\"ON\" type=\"submit\">VORW</button>") ;
client.println("<button class=\"button\" name=\"LED1\" value=\"OFF\" type=\"submit\">RUECKW</button></center>");
client.println("<p>motor ist " + LED_TWO_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED2\" value=\"ON\" type=\"submit\">AN</button>");
client.println("<button class=\"button\" name=\"LED2\" value=\"OFF\" type=\"submit\">AUS</button></center>");
client.println("<p>geschwindigkeit ist " + LED_THREE_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED3\" value=\"ON\" type=\"submit\">SCHNELLER</button>");
client.println("<button class=\"button\" name=\"LED3\" value=\"OFF\" type=\"submit\">LANGSAMMER</button></center>");
client.println("<p>kamera ist " + LED_FOUR_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED4\" value=\"ON\" type=\"submit\">AN</button>");
client.println("<button class=\"button\" name=\"LED4\" value=\"OFF\" type=\"submit\">AUS</button></center>");
client.println("</center></form></body></html>");
client.println();
break;
}
else
{
current_data_line = "";
}
}
else if (new_byte != '\r')
{
current_data_line += new_byte;
}
}
}
naja, dass, was jetzt bereits im arduino läuft - läuft ja. Zunächst ist das ja ausreichend. Es geht mir letztendlich darum , dass ich - je nach situation - den roboter per IR-fernbedienung oder smartphone steuen kann...
edit: foto hinzu...
Anhang 34497
Der Link (Anhang 34495) funktioniert nicht.
Fehler:
- - - Aktualisiert - - -Zitat:
Ungültige Angabe: Anhang
Wenn du einem normalen, gültigen Link im Forum gefolgt bist, wende dich bitte an den Webmaster.
Ok, Bild ist jetzt da.
ich hatte im nachinein auch probleme das bild darzustellen, keine ahnung was da war...
ich finde es toll, dass Du mir hilfst, würde aber sehr gerne an Deinen überlegungen teilhaben wollen - wenn's denn nicht zu viel verlangt ist :-) - also auch mit evtl. irrwegen, meinen dummen fragen usw...
Na gut, wenn Du das alles nachvollziehen willst, musst Du selber ran, an den Code, aber mit Unterstützung / Hilfe.
Das Bild bearbeite ich mal und verpacke das in eine komprimierte Datei, JPEG oder so - was am wenigsten Platz benötigt.
Die Datei kann in das "Filesystem" auf dem nodeMCU geschrieben werden, damit belegt es keinen Programmspeicher. Allerdings kommt dann wieder zusätzlicher Programmcode, für SPIFF hinzu.
Oder zweitens, ich codiere die Dateigleich zu Base64 und diesen String kann man dann direkt in den Programmcode integrieren. Das wäre vielleicht zu Anfang die einfachste Methode.
MfG
okay, das war ein bischen zu schnell für'n alten man :-(
muss ich das manuell machen und nur einmal, oder macht das das programm? Und was ist SPIFF?Zitat:
Die Datei kann in das "Filesystem" auf dem nodeMCU geschrieben werden, damit belegt es keinen Programmspeicher. Allerdings kommt dann wieder zusätzlicher Programmcode, für SPIFF hinzu.
ok, die einfachste methode, aber bitte was ist Base64?Zitat:
Oder zweitens, ich codiere die Datei gleich zu Base64 und diesen String kann man dann direkt in den Programmcode integrieren. Das wäre vielleicht zu Anfang die einfachste Methode.
Du siehst schon, viele von den begriffen von damals haben nicht überlebt :-(...
Ich glaube wir müssen es etwas anders aufbauen. Mit beispielen. Und ich weiss nicht, ob Dir das nicht zu viel wird :-(
edit:
base64 (ungefähr =) open PGP - und PGP ist mir von früher her ein begriff
SPIFF -flash-speicher?
-----------------------
aber Du musst schon etwas langsammer machen :-)
Das ist zunächst der erste Schritt:
Ich habe jetzt mal das Bild bearbeitet und verkleinert, dass es noch eine annehmbare Zahl an Details enthält, wenn das Bild nachher im Browser dargestellt wird, sollte der die Pixelübergänge weichzeichnen.
Hier ist erst einmal der String, wie der dann aussieht:
Weil das 9KByte sind, hier als Textdatei: Anhang 34498Code:data:image/png;base64,iVBORw....AElFTkSuQmCC
Base64 ist eine Codierung, die Hex-Code in Zeichencode umwandelt (ganz einfach ausgedrückt). So kann der auch im Webseitencode transportiert werden. Damit kann man eine DATA-URL erzeugen, direkt im Webseitencode, der Browser erkennt das und stellt die Grafik dann als solche dar, weil er das zuvor dekodiert. Man kann diesen String aber auch direkt im Browser, oben in der URL-Zeile, eingeben (reinkopieren), der Browser sollte dann das Bild darstellen (es ist in dem Moment eine Data-URL). Wenn Du es ausprobierst, wird Dir sicher alles klar.
MfG
- - - Aktualisiert - - -
SPIFF ist das File System, dass auf einem nodeMCU emuliert wird. Ein ESP-12E hat 1MByte Programmspeicher und 3MByte für SPIFFs (zusätzlicher Flash-Speicher für Dateien). In der Arduino-IDE kann man Dateien im Menü "Werkzeuge" mit "Sketch Data Upload" hochladen. So wie man den Programmcode in den Programmspeicher hochlädt. So, wie Du eine SD-Karte verwenden kannst, kannst Du auch diesen Speicher per SPIFFs verwenden. Wieviel der ESP32 hat, weiß ich nicht, habe noch keinen ESP32.
Anhang 34499
war das so gemeint?
Nein! Du hast den Kurzen aus dem Veranschaulichungsbeispiel genommen! :Haue
Du musst den langen String aus der Textdatei nehmen, nur der ist vollständig. :-b
- - - Aktualisiert - - -
Zweiter Schritt dann:
Wir bauen einfach eine Tabelle, wo die Grafik als Hintergrundbild dient.
jaja, hau nur drauf...
das sieht aber schon besser aus jetzt:
Anhang 34500
den zweck musst Du mir aber bei passender gelegenheit erklären...
Ich habe aber gerade nochmal nachgesehen, statt Tabelle können wir wohl auch eine Image Map in HTML benutzen. Dafür sind diese Dinger da. Das würde die Sache erleichtern.
Also nehmen wir dann dieses Bild und erzeugen damit in HTML eine Map, also Karte, mit den Koordinaten, wo was angeklickt werden kann.
Wofür das oben gut ist? Du siehst, dass man diesen 9KByte langen String als Text kopieren kann und sich darin Dein Bild befindet.
MfG
- - - Aktualisiert - - -
Nächster Schritt
Ich habe schon mal eine Tabelle, als Rahmen, erstellt und das ganz einfach als HTM-Datei gespeichert.
Zuerst muss die Tabelle definiert werde, dann in der Tabelle drei Zeilen und jede Zeile enthält drei Zellen.
Die mittlere Zelle bekommt später als Inhalt die Image Map, also das Bild der Fernbedienung.
Die Tabelle dient als Rahmen um das Bild, damit die Fernbedienung dem Original nahe kommt.
Ich habe bei dem Bild zunächst alle Ränder abgeschnitten, damit wir Speicherplatz sparen.
Die Ränder sind mit der Tabelle wieder hinzugefügt. Belegen damit 928Byte, also knapp 1KByte, zusätzlich zum Bild.
Hier erstmal die Datei mit den Rohdaten: Anhang 34501
Die Datei ist als *.TXT gespeichert. Die Endung kann umbenannt werden von ".txt" in ".htm", um sie im Browser zu laden und anzuschauen.
Fragen so weit? Wir machen weiter, wenn nicht.
MfG
- - - Aktualisiert - - -
Zur Erläuterung des HTML-Codes
Die Tabelle ist so aufgebaut:
Code:TABELLE
.......TABELLENZEILE
...................TABELLENZELLE|TABELLENZELLE|TABELLENZELLE
.......TABELLENZEILE
...................TABELLENZELLE|TABELLENZELLE|TABELLENZELLE
.......TABELLENZEILE
...................TABELLENZELLE|TABELLENZELLE|TABELLENZELLE
Die Tabelle hat also sechs Zellen, in drei Zeilen.
------------------------------------------------------------------
Die Tabelle ist definiert mit:
Code:<div style='display:table;background:#000000;border-radius:2em'>
display:table ... DIV-Container als Tabelle
background ... #000000 = hexadezimale Notation für RGB (Rot/Grün/Blau) ergibt hier schwarz
border-radius ... damit die Ecken der Tabelle rund werden, die Zahl gibt den Durchmesser an
Maßeinheit: ich verwende immer "em", diese Maßeinheit ist skalierbar. 1em sind normalerweise 16 Pixel, aber nicht in jedem Browser, hängt mit der Basis-Schriftgröße zusammen; Pixel "px" wäre eine absolute Größe und ist unpraktisch, wir wollen später sehen, dass sich unsere HTML-Fernbedienung an die Größe Deines Smartphone-Bildschirms anpasst
------------------------------------------------------------------
Eine Tabellenzeile ist definiert mit:
Code:<div style='display:table-row'>
display:table-row ... DIV-Container als Tabellenzeile
------------------------------------------------------------------
Eine Tabellenzelle ist definiert mit:
Code:<div style='display:table-cell;width:3em;height:3em'>
display:table-cell ... DIV-Container als Tabellenzelle
width ... Breite einer Zelle
height ... Höhe einer Zelle
oh, Moppi, Du bist mir viel zu schnell :-), morgen geht's weiter, wenn ich alles verstanden hab...
gruss inka
Ich habe keine Zeit zu verlieren :)
Guck es Dir ruhig an. Dann kommt noch die Image Map, das ist nicht allzu schwer. Dann müssen wir sehen, dass der HTML-Code das macht, was er soll und dann muss der in Dein Programm eingebunden werden.
Ist schon spät heute.
MfG
Hallo inka!
Ich habe da mal noch eine Versuchsdatei: Anhang 34503
Wieder Endung ".txt" in ".htm" umbenennen und mit dem Webbrowser laden.
Daran ist zu sehen, wie das mit der Image Map funktioniert.
Hier der Teil der Map:
Mit width und height wird die Breite und Höhe des Bildes angegeben. Usemap verweist auf die Map mit dem Namen "Remote".Code:<img width='170' height='372' usemap='#Remote' src='data:image/png;base64,iVBO...uQmCC'>
<map name='Remote'>
<area shape='circle' coords='84,26,22' href='..'>
</map>
Weil zu dem Bild eine "Karte" mit Koordinaten angegeben werden muss - der Bereich "area", wo sich eine Taste, auf dem Bild der Fernbedienung, befindet. Für die oberste Taste ist das die Position 84 Pixel von links und 26 Pixel von oben, mit einem Radius (weil die Tasten rund sind) von 22 Pixel. Angegeben wird das alles in "<area ...>". "shape='circle'" wird verwendet, weil wir einen Kreis, als Bereich, definieren. "src=..." ist die Quelle des Bildes für die Map, hier setzen wir den Base64-kodierten String unseres Bildes ein.
Und nun haben wir ein Problem, das mir nicht gefällt. Hätte ich ganz zu Anfang dran denken können, das zu überprüfen (obwohl ich schon einmal Image Maps verwendet habe, ist allerdings schon etwa 15 Jahre her): die Image Map arbeitet nur mit Pixel. Wir können keine Koordinaten verwenden, die einfach skaliert werden können, indem wir ein anderes Maß, als eben Pixel, verwenden. Falls das doch irgendwie machbar sein sollte, weiß ich noch nicht wie.
Das bedeutet, dass die Tabelle und das Bild - also die Fernbedienung in HTML - in Pixel definiert wird (was ich in der Beispieldatei schon gemacht habe). Sollte die Fernbedienung, in Pixel, breiter oder höher sein, als der Smartphone-Bildschirm, passt die dort nicht vollständig drauf und muss horizontal und/oder vertikal gescrollt werden. Natürlich kann man die Pixelmaße dann an seinen Smartphone- oder Tablet-Bildschirm anpassen, es bleibt aber eine feste Angabe.
Ich lass das erst einmal so stehen. Schau es Dir zunächst einmal an. Dann schauen wir weiter.
-------------
Gleich noch etwas weiter drüber nachgedacht: die Pixelangaben können nachher im Programm berechnet und in die HTML-Seite eingesetzt werden, basierend auf einer vorgegebenen Breite und Höhe (z.B. Displaygröße in Pixel v. Smartphone). Damit kann die Größe der HTML-Fernbedienung auch nachjustiert werden. Aber das jetzt erst einmal nur so nebenbei.
MfG
die darstellung auf dem smartphone sieht so aus:
Anhang 34504
ich meine, es muss nicht sein, dass die html fernbedienung das ganze display ausfüllt, toll (und völlig ausreichend) wäre es, wenn es in etwa zentriert zum display wäre.
Die anderen sachen habe ich mir angeschaut, selber programmieren könnte ich es nicht, aber ich habe verstanden wo Du was und wie gemacht hast, müsste also in der lage sein kleine korrekturen selbst durchführen zu können. Toll erklärt!