RC Benchy 2.0
Obliczymy ostateczną cenę na podstawie wybranego pliku. Sprawdzisz ją i zaakceptujesz przed płatnością.
Zapisane na tym urządzeniu.
This powerful RC Benchy is ment to pull you in a dingy or a SUP
- Ocena
- 5 / 5
- Polubienia
- 130
- Pobrania
- 611
- Wydruki
- 1
- Wyświetlenia
- 3985
- Oceny
- 1
Aktualizacja u źródła:
Informacje o modelu
- Źródło
- Printables
- Kategoria
- RC & Robotics
- Licencja
- Creative Commons — Attribution
Ich empfehle jedem die Version mit den Unterwassermotoren zu drucken, da sie deutlich besser funktioniert und noch ein bisschen optimiert worden ist.





Alle Teile die ihr zum nachbauen findet ihr hier:
Dichtband: https://amzn.to/4jjP1x7
Esp 8266: https://amzn.to/43rXUhZ
Wasserdichte Knöpfe: https://amzn.to/3H9MR5W
Akku Doppelpack: https://amzn.to/459B2GT
Akku inkl. Ladegerät: https://amzn.to/45kAqhu
2x ESC Wassergekühlt: https://amzn.to/44Qbn5H
2x ESC ungekühlt: https://amzn.to/4ms6nKU
2x Unterwassermotor: https://amzn.to/43aXXQB
Schiffsschrauben: https://amzn.to/4moC7R3
Dichtol Spray: https://amzn.to/43HND2z
Lochrasterplatine: https://amzn.to/43uxwnU
M4 Gewindeeinsätze: https://cnckitchen.store/de/products/heat-set-insert-m4-x-8-1-50-pieces
Der Code für die Fernsteuerung:
IHR MÜSST DIE IP ADRESSE ZU DER VON EUREM EMPFÄNGER ESP ÄNDERN!
#include <ESP8266WiFi.h>
#include <espnow.h>// REPLACE WITH THE MAC Address of your receiver
uint8_t broadcastAddress[] = {0xEC, 0x64, 0xC9, 0xDE, 0x34, 0x2F};
//Structure to send data
//Must match the receiver structure
typedef struct struct_message {
int l;
int r;
int f;
} struct_message;
// Create a struct_message called myData
struct_message myData;
// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
Serial.print("Last Packet Send Status: ");
if (sendStatus == 0){
Serial.println("Delivery success");
}
else{
Serial.println("Delivery fail");
}
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
pinMode(D6, INPUT); // Sets the linkspin as an Input
pinMode(D5, INPUT); // Sets the rechtspin as an Input
pinMode(D7, INPUT); // Sets the forwärtspin as an Input
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_register_send_cb(OnDataSent);
// Register peer
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
void loop() {
// Set values to send
myData.l = digitalRead(D6); //Button links auslesen und Status in Message speichern
myData.r = digitalRead(D5); //Button rinks auslesen und Status in Message speichern
myData.f = digitalRead(D7); //Button gerade auslesen und Status in Message speichern
Serial.print("Button Links: ");
Serial.println(digitalRead(D6));
Serial.print("Button Rechts: ");
Serial.println(digitalRead(D5));
Serial.print("Button Forne: ");
Serial.println(digitalRead(D7));
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
delay(1);
}
Empfänger Code:
#include <ESP8266WiFi.h>
#include <espnow.h>
#include <Servo.h>
Servo MotorL;
Servo MotorR;
int s = 40;
int g = 0;
int incomingl = 0;
int incomingr = 0;
int incomingf = 0;
const int rampdauer = 2000; // 1 Sekunden in Millisekunden
const int resetZeit = 100;
//Structure example to send data
//Must match the receiver structure
typedef struct struct_message {
int l;
int r;
int f;
} struct_message;
// Create a struct_message called myData
struct_message myData;
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));
incomingl = myData.l;
incomingr = myData.r;
incomingf = myData.f;
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
MotorL.attach(5); // GPIO 5 ist D1
MotorR.attach(4); // GPIO 4 ist D2
MotorL.write(0);
MotorR.write(0);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
}
void loop() {
if (incomingl != 0 || incomingr != 0 || incomingf != 0) {
// steuerbefehl vorwärts prüfen
if (incomingf == 1){
if (incomingr == 1 || incomingl == 1){
if (incomingl == 1){
GasRampL(s);
GasRampR(s/2);
g = 0;
Serial.println("Gas und Links");
delay(1);
}
if (incomingr == 1){
GasRampL(s/2);
GasRampR(s);
g = 0;
Serial.println("Gas und Rechts");
delay(1);
}
} else {
GasRampL(s);
GasRampR(s);
g = 0;
Serial.println("Vorwärtsgas");
delay(1);
}
} else {
if (incomingl == 1){
GasRampL(s);
g = 0;
Serial.println("Nur links");
delay(10);
} else if (incomingr == 1){
GasRampR(s);
g = 0;
Serial.println("Nur Rechts");
delay(1);
}
}
} else {
// Stop the motors when no signal is received
MotorL.write(0);
MotorR.write(0);
Serial.println("Motors stopped");
delay(5);
}
}
void GasRampL(int zielWert) {
// Lokale statische Variablen, die ihren Wert zwischen den Funktionsaufrufen behalten
static unsigned long startZeit = 0; // Zeitpunkt, an dem die Rampensteuerung begonnen hat
static unsigned long letzterAufruf = 0; // Zeitpunkt des letzten Funktionsaufrufs
static int gasWert = 10; // Aktueller Gaswert, der hochfährt
// Berechne die aktuelle Zeit
unsigned long aktuelleZeit = millis();
unsigned long vergangeneZeit = aktuelleZeit - startZeit;
// Wenn die Funktion seit mehr als 50 ms nicht aufgerufen wurde, setze den Gaswert zurück
if (aktuelleZeit - letzterAufruf > resetZeit) {
gasWert = 10; // Gaswert zurücksetzen
startZeit = aktuelleZeit; // Starte neue Ramp-Zeit
}
// Überprüfe, ob die Rampendauer erreicht wurde
if (vergangeneZeit < rampdauer) {
// Berechne den aktuellen Gaswert in Abhängigkeit von der Zeit
gasWert = map(vergangeneZeit, 0, rampdauer, 10, zielWert);
} else {
// Wenn die Zeit abgelaufen ist, bleibt der Gaswert auf dem Zielwert
gasWert = zielWert;
}
// Ausgabe des aktuellen Gaswertes
Serial.print("Gaswert: ");
Serial.println(gasWert);
// Motorsteuerung (MotorL.write, falls Servo oder PWM)
MotorL.write(gasWert);
// Aktualisiere die Zeit des letzten Aufrufs
letzterAufruf = aktuelleZeit;
}
void GasRampR(int zielWert) {
// Lokale statische Variablen, die ihren Wert zwischen den Funktionsaufrufen behalten
static unsigned long startZeit = 0; // Zeitpunkt, an dem die Rampensteuerung begonnen hat
static unsigned long letzterAufruf = 0; // Zeitpunkt des letzten Funktionsaufrufs
static int gasWert = 10; // Aktueller Gaswert, der hochfährt
// Berechne die aktuelle Zeit
unsigned long aktuelleZeit = millis();
unsigned long vergangeneZeit = aktuelleZeit - startZeit;
// Wenn die Funktion seit mehr als 50 ms nicht aufgerufen wurde, setze den Gaswert zurück
if (aktuelleZeit - letzterAufruf > resetZeit) {
gasWert = 10; // Gaswert zurücksetzen
startZeit = aktuelleZeit; // Starte neue Ramp-Zeit
}
// Überprüfe, ob die Rampendauer erreicht wurde
if (vergangeneZeit < rampdauer) {
// Berechne den aktuellen Gaswert in Abhängigkeit von der Zeit
gasWert = map(vergangeneZeit, 0, rampdauer, 10, zielWert);
} else {
// Wenn die Zeit abgelaufen ist, bleibt der Gaswert auf dem Zielwert
gasWert = zielWert;
}
// Ausgabe des aktuellen Gaswertes
Serial.print("Gaswert: ");
Serial.println(gasWert);
// Motorsteuerung (MotorR.write, falls Servo oder PWM)
MotorR.write(gasWert);
// Aktualisiere die Zeit des letzten Aufrufs
letzterAufruf = aktuelleZeit;
}