Hirdetés
- NVIDIA GeForce RTX 5070 / 5070 Ti (GB205 / 203)
- 5.1, 7.1 és gamer fejhallgatók
- Milyen asztali (teljes vagy fél-) gépet vegyek?
- Nvidia GPU-k jövője - amit tudni vélünk
- Vezeték nélküli fülhallgatók
- Milyen monitort vegyek?
- Fejhallgató erősítő és DAC topik
- 3D nyomtatás
- AMD Ryzen 9 / 7 / 5 9***(X) "Zen 5" (AM5)
- A HBM elérhetősége korlátozza a kínai AI gyorsítókat
-
PROHARDVER!
Arduino hardverrel és szoftverrel foglakozó téma. Minden mikrovezérlő ami arduinoval programozható, és minden arduino program, board, és hardverrel kapcsolatos kérdések helye.
Új hozzászólás Aktív témák
-
Postas99
őstag
A legtöbb szervo 360-as amin van a maradék 180-as. Itt a kód:
#include <Arduino.h>
#include "driver/gpio.h"
#include "esp_timer.h"
// ---- SZERVÓ
static const int SERVO_L_PIN = 18; // bal
static const int SERVO_R_PIN = 19; // jobb
// ---- TRIGGER
static const int TRIG_L = 32; // 1x bal: előre->stop->vissza->stop
static const int TRIG_R = 33; // 1x jobb: hátra->stop->előre->stop
static const int TRIG_BOTH = 25; // 1x mindkettő (bal előre, jobb hátra) - belső PULLUP!
static const uint32_t FRAME_US = 20000; // 20 ms, 50 Hz
// ---- BAL/JOBB PULSE (µs) + állapot ----
volatile uint32_t pulse_us_L = 1500; // 1000..2000
volatile uint32_t pulse_us_R = 1500;
volatile bool highPhase_L = false;
volatile bool highPhase_R = false;
portMUX_TYPE muxServo = portMUX_INITIALIZER_UNLOCKED;
// ---- TIMER HANDLE-K ----
esp_timer_handle_t tmrL;
esp_timer_handle_t tmrR;
inline void setLeftPulseUs(uint32_t us) {
if (us < 1000) us = 1000; if (us > 2000) us = 2000;
portENTER_CRITICAL(&muxServo); pulse_us_L = us; portEXIT_CRITICAL(&muxServo);
}
inline void setRightPulseUs(uint32_t us) {
if (us < 1000) us = 1000; if (us > 2000) us = 2000;
portENTER_CRITICAL(&muxServo); pulse_us_R = us; portEXIT_CRITICAL(&muxServo);
}
// ---- PWM
void IRAM_ATTR cbLeft(void*) {
uint32_t p; portENTER_CRITICAL_ISR(&muxServo); p = pulse_us_L; portEXIT_CRITICAL_ISR(&muxServo);
if (!highPhase_L) { gpio_set_level((gpio_num_t)SERVO_L_PIN, 1); highPhase_L = true; esp_timer_start_once(tmrL, p); }
else { gpio_set_level((gpio_num_t)SERVO_L_PIN, 0); highPhase_L = false; esp_timer_start_once(tmrL, (p<FRAME_US)?(FRAME_US-p):1000); }
}
void IRAM_ATTR cbRight(void*) {
uint32_t p; portENTER_CRITICAL_ISR(&muxServo); p = pulse_us_R; portEXIT_CRITICAL_ISR(&muxServo);
if (!highPhase_R) { gpio_set_level((gpio_num_t)SERVO_R_PIN, 1); highPhase_R = true; esp_timer_start_once(tmrR, p); }
else { gpio_set_level((gpio_num_t)SERVO_R_PIN, 0); highPhase_R = false; esp_timer_start_once(tmrR, (p<FRAME_US)?(FRAME_US-p):1000); }
}
// ---------- MOZGÁS
const int NEUTRAL_L = 1500, NEUTRAL_R = 1500;
const int L_FWD_US = 1600, L_BACK_US = 1400;
const int R_FWD_US = 1600, R_BACK_US = 1400;
const unsigned long L_FWD_MS = 190;
const unsigned long L_BACK_MS = 186;
const unsigned long R_FWD_MS = 205;
const unsigned long R_BACK_MS = 181;
const unsigned long STOP1_MS = 1000;
const unsigned long STOP2_MS = 1000;
enum SPhase { S_IDLE, S_FWD, S_STOP1, S_BACK, S_STOP2 };
SPhase L_phase = S_IDLE, R_phase = S_IDLE;
unsigned long L_nextUs = 0, R_nextUs = 0;
// Indítások (csak ha IDLE)
void startLeftCycle() {
if (L_phase != S_IDLE) return;
setLeftPulseUs(L_FWD_US);
L_phase = S_FWD;
L_nextUs = micros() + L_FWD_MS * 1000UL;
}
void startRightCycle_BackThenFwd() {
if (R_phase != S_IDLE) return;
setRightPulseUs(R_BACK_US);
R_phase = S_BACK;
R_nextUs = micros() + R_BACK_MS * 1000UL;
}
void startBothCycleMirrored() {
if (L_phase != S_IDLE || R_phase != S_IDLE) return; // egyszerre csak ha mindkettő szabad
unsigned long now = micros();
setLeftPulseUs(L_FWD_US); L_phase = S_FWD; L_nextUs = now + L_FWD_MS * 1000UL;
setRightPulseUs(R_BACK_US); R_phase = S_BACK; R_nextUs = now + R_BACK_MS * 1000UL;
}
inline void serviceLeft() {
if (L_phase == S_IDLE) return;
unsigned long now = micros();
if ((long)(now - L_nextUs) < 0) return;
switch (L_phase) {
case S_FWD: setLeftPulseUs(NEUTRAL_L); L_phase = S_STOP1; L_nextUs = now + STOP1_MS * 1000UL; break;
case S_STOP1: setLeftPulseUs(L_BACK_US); L_phase = S_BACK; L_nextUs = now + L_BACK_MS * 1000UL; break;
case S_BACK: setLeftPulseUs(NEUTRAL_L); L_phase = S_STOP2; L_nextUs = now + STOP2_MS * 1000UL; break;
case S_STOP2: setLeftPulseUs(NEUTRAL_L); L_phase = S_IDLE; break;
default: break;
}
}
inline void serviceRight() {
if (R_phase == S_IDLE) return;
unsigned long now = micros();
if ((long)(now - R_nextUs) < 0) return;
switch (R_phase) {
case S_BACK: setRightPulseUs(NEUTRAL_R); R_phase = S_STOP1; R_nextUs = now + STOP1_MS * 1000UL; break;
case S_STOP1: setRightPulseUs(R_FWD_US); R_phase = S_FWD; R_nextUs = now + R_FWD_MS * 1000UL; break;
case S_FWD: setRightPulseUs(NEUTRAL_R); R_phase = S_STOP2; R_nextUs = now + STOP2_MS * 1000UL; break;
case S_STOP2: setRightPulseUs(NEUTRAL_R); R_phase = S_IDLE; break;
default: break;
}
}
// ---- GOMBOLVASÁS
const unsigned long DEBOUNCE_MS = 30;
int prevL = HIGH, prevR = HIGH, prevB = HIGH;
unsigned long lastEdgeL = 0, lastEdgeR = 0, lastEdgeB = 0;
void setup() {
// Szervó kimenetek
gpio_set_direction((gpio_num_t)SERVO_L_PIN, GPIO_MODE_OUTPUT);
gpio_set_direction((gpio_num_t)SERVO_R_PIN, GPIO_MODE_OUTPUT);
gpio_set_level((gpio_num_t)SERVO_L_PIN, 0);
gpio_set_level((gpio_num_t)SERVO_R_PIN, 0);
// Két független esp_timer
esp_timer_create_args_t aL = {}; aL.callback = &cbLeft; aL.name = "servoL";
esp_timer_create_args_t aR = {}; aR.callback = &cbRight; aR.name = "servoR";
ESP_ERROR_CHECK(esp_timer_create(&aL, &tmrL));
ESP_ERROR_CHECK(esp_timer_create(&aR, &tmrR));
ESP_ERROR_CHECK(esp_timer_start_once(tmrL, 100));
ESP_ERROR_CHECK(esp_timer_start_once(tmrR, 100));
// Kezdő állás (IDLE, tartó jel 1500 µs)
setLeftPulseUs(NEUTRAL_L);
setRightPulseUs(NEUTRAL_R);
pinMode(TRIG_L, INPUT_PULLUP);
pinMode(TRIG_R, INPUT_PULLUP);
pinMode(TRIG_BOTH, INPUT_PULLUP); // 25-ön VAN belső PULLUP
prevL = digitalRead(TRIG_L);
prevR = digitalRead(TRIG_R);
prevB = digitalRead(TRIG_BOTH);
}
void loop() {
unsigned long nowMs = millis();
// 32: bal
int rl = digitalRead(TRIG_L);
if (rl != prevL) { prevL = rl; lastEdgeL = nowMs; }
if (rl == LOW && (nowMs - lastEdgeL) > DEBOUNCE_MS) {
startLeftCycle();
lastEdgeL = nowMs + 300; // primitív ismétlésgátló
}
// 33: jobb
int rr = digitalRead(TRIG_R);
if (rr != prevR) { prevR = rr; lastEdgeR = nowMs; }
if (rr == LOW && (nowMs - lastEdgeR) > DEBOUNCE_MS) {
startRightCycle_BackThenFwd();
lastEdgeR = nowMs + 300;
}
// 25: egyszerre mindkettő
int rb = digitalRead(TRIG_BOTH);
if (rb != prevB) { prevB = rb; lastEdgeB = nowMs; }
if (rb == LOW && (nowMs - lastEdgeB) > DEBOUNCE_MS) {
startBothCycleMirrored();
lastEdgeB = nowMs + 300;
}
serviceLeft();
serviceRight();
delay(1); // kis yield
}[/M][/M]
Új hozzászólás Aktív témák
- Eladó két darab JBL PartyBox 520 hangszóró újszerű állapot, 34hónap garanciával!
- Megválnék a fotós arzenálomtól 6D MkII, Sigma üvegek, vakuk, és még sok más
- DELL T3620 WORKSTATION INTEL XEON I7-6700 / NVME SSD / DDR4 - vga tápkábel
- Gamer PC - R5 5500, RTX 2060 és 16gb RAM + GARANCIA
- 2025-Ös 10 Magos Legújabb Intel Core Ultra 5 225F 10x4.9Ghz RTX 5060TI 16/32Gb DDR5 5600Mhz 1TB M.2
- 6 GB-os Quadro RTX A2000 kártyák - garanciával
- GYÖNYÖRŰ iPhone 13 Pro 128GB Graphite -1 ÉV GARANCIA - Kártyafüggetlen, MS3082
- APC UPS 950VA (BX950MI-GR)
- DELL Precision Dual USB-C Thunderbolt Dock - TB18DC
- ÁRGARANCIA!Épített KomPhone Ryzen 5 7600X 32/64GB RAM RTX 5070 12GB GAMER PC termékbeszámítással
Állásajánlatok
Cég: PCMENTOR SZERVIZ KFT.
Város: Budapest
Cég: CAMERA-PRO Hungary Kft.
Város: Budapest