Ciao a tutti. Sto cercando da un pò di fare funzionare Arduino con un modulo TMC2209, ma il problema è che voglio inviare e ricevere via UART. Non ci sono molte guide su internet ho letto pochi post anche sul forum inglese.
Ho collegato i pin EN, DIR, STEP e quello che penso sia il pin PDN_UART, e 5v e GND ovviamente.
Ho letto che con questo modulo si usa il collegamento Half-Duplex e quindi non ci sono due pin RX e TX. Usando un microscopio digitale credo di avere capito che il pin PDN_UART del chip va al 4° pin fisico del modulo, sotto EN.
Quindi lo ho collegato a un pin di Arduino tramite una resistenza da 1Kohm e ho scritto un codice per verificare se riesco a modificare il valore di microstepping che a quanto pare risulta essere sempre 256.
Qualcuno ha esperienza con questo modulo?
Supponendo che usi arduino classico e sofware serial e che vuoi usare solo Tx, non hai bisogno di resistenza 1k in serie. Quarto pin da EN sembra corretto.
Hai provato esempio da libreria?
Grazie della risposta.
Sto provando un codice che ho organizzato il più file. Sto cercando di capire se la comunicazione UART funziona oppure no cercando di scrivere e leggere il valore di microstepping con queste righe nel loop():
driver.microsteps(1); // IMPOSTA valore
uint16_t currentMicrosteps = driver.microsteps(); // LEGGE valore dal driver
updateOLED(currentMicrosteps); // (funzione display oled in un altro file .cpp)
Ma continuo a leggere sempre 256 sul display. Con un pulsante riesco a fare girare il motore (non sto usando il classico NEMA, ma un 28-byj-48 a 12v modificato a bipolare). Ma anzichè fare un giro completo (2048 steps) fa meno di 1/4 di giro.
Se necessario posso postare tutti i file del progetto.
Allora, che arduino, sw o hw serial, solo tx o rx/tx, che libreria?
No io vorrei sia trasmettere che ricevere dal modulo.
Quindi la resistenza da 1k la devo togliere?
Sto usando un Atmega328p che programmo con Arduino Uno. Ho saldato il modulo e tutti i componenti su una pcb (l'unico componente non saldato è l'Atmega, che sposto dalla breadboard allo zoccolo sulla pcb di volta in volta).
Posto il codice completo così non ci sbagliamo, sono in tutto 6 file. Mi spiace se il tutto è confuso comunque ecco:
main.ino:
#include <TMCStepper.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
// altre schede
#include "oled_display.h"
#include "motor_control.h"
#include "config.h"
#define TMC_RX_PIN 6 // Arduino TX -> TMC RX (tramite resistenza 1Kohm)
#define TMC_TX_PIN 5 // Arduino RX <- TMC TX
// OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
// Setup SoftwareSerial (Rx, Tx)
SoftwareSerial tmcs(TMC_TX_PIN, TMC_RX_PIN); // RX, TX
#define R_SENSE 0.11f
TMC2209Stepper driver(&tmcs, R_SENSE, 0x00); // Aggiunto indirizzo 0x00
void setup() {
pinMode(EN_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
pinMode(TMC_RX_PIN, INPUT);
pinMode(TMC_TX_PIN, OUTPUT);
digitalWrite(EN_PIN, LOW); // Enable driver
// OLED init
setupOLED(); // Inizializza il display una sola volta
// Setup SoftwareSerial UART a 115200
tmcs.begin(19200); // test 19200 prima di tornare a 115200
delay(100);
driver.begin();
driver.toff(5);
driver.rms_current(600);
driver.en_spreadCycle(false);
driver.pwm_autoscale(true);
driver.microsteps(1);
}
unsigned long currentMillis;
unsigned long previousMillis = 0;
unsigned long oledPreviousMillis = 0; //--
const long interval = 500; // 500 ms led lampeggiante
bool ledState = false;
bool buttonPressed = false;
void loop() {
currentMillis = millis();
// LED blink
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
ledState = !ledState;
digitalWrite(LED_PIN, ledState);
}
// Aggiorna display
if (currentMillis - oledPreviousMillis >= 300) {
oledPreviousMillis = currentMillis;
driver.microsteps(1);
uint16_t currentMicrosteps = driver.microsteps(); // LEGGE valore dal driver
updateOLED(currentMicrosteps);
}
// Pulsante
if (digitalRead(BUTTON_PIN) == LOW && !buttonPressed) {
buttonPressed = true;
startMoveSteps(NUM_STEPS);
}
if (digitalRead(BUTTON_PIN) == HIGH) {
buttonPressed = false;
}
// Gestione motore
updateMotor();
}
config.h:
#ifndef CONFIG_H
#define CONFIG_H
// Pin
#define EN_PIN 7
#define STEP_PIN 4
#define DIR_PIN 3
#define BUTTON_PIN 9
#define LED_PIN 2
#define NUM_STEPS 2048
#define TMC_TX_PIN 5
#endif
motor_control.cpp:
#include <Arduino.h>
#include "motor_control.h"
#include "config.h"
static int stepsToDo = 0;
static int stepsDone = 0;
static unsigned long lastStepTime = 0;
static const unsigned int stepDelayMicros = 1000; // 1ms per passo
static bool motorMoving = false;
void startMoveSteps(int steps) {
stepsToDo = steps;
stepsDone = 0;
lastStepTime = micros();
motorMoving = true;
}
void updateMotor() {
if (!motorMoving) return;
unsigned long now = micros();
if (now - lastStepTime >= stepDelayMicros) {
lastStepTime = now;
// Un impulso
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(5); // breve HIGH per segnale valido
digitalWrite(STEP_PIN, LOW);
stepsDone++;
if (stepsDone >= stepsToDo) {
motorMoving = false;
}
}
}
bool isMotorMoving() {
return motorMoving;
}
motor_control.h:
#ifndef MOTOR_CONTROL_H
#define MOTOR_CONTROL_H
void startMoveSteps(int steps);
void updateMotor();
bool isMotorMoving(); //
#endif
oled_display.cpp:
#include "oled_display.h"
#include "config.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
// Config display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setupOLED() {
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
Serial.println("ERRORE OLED!");
return;
}
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("OLED OK");
display.display();
}
void updateOLED(uint16_t microsteps) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Microsteps:");
display.setCursor(0, 30);
display.print(microsteps);
display.display();
}
oled_display.h:
#ifndef OLED_DISPLAY_H
#define OLED_DISPLAY_H
#include <Arduino.h>
#include <Adafruit_SSD1306.h>
extern Adafruit_SSD1306 display;
void setupOLED();
void updateOLED(uint16_t microsteps);
#endif
ed è tutto il progetto almeno fin'ora.
Arduino softwareserial generalmente non puo' usato per uart bidirezionale con TMC2209
Non conosco libreria che usi, ma probabilmente lo manipola qualche modo intelligente.
parametri validi sono 0,2,4,8,...256
Ho provato a modificare il valore in (0) e in (16) ma non funziona.
Ho anche ripetuto questo progetto su breadboard ma non funziona. Ricevo "microsteps: 256 e current: 1049". Strano perchè lo ho ripetuto uguale eppure non funziona ma l'autore dice che funzionava.
Ho letto che a seconda del modulo acquistato ci sono degli spazi da saldare per abilitare UART, quindi più che altro vorrei subito se il problema è del modulo.
Non c'è qualcuno che può confermarmi che il modulo è ok tramite delle foto? Oppure se c'è qualcosa da sadvare o il pin che uso per UART non è quello giusto.
Immagini:
Il pin PDN_UART è quello in alto che va al resitore SMD più a destra, che dall'altro capo va al connettore (giallo) centrale nell'immagine. Quello è il connettore che uso per UART arduino.
Ci sono tante schede con circuiti diversi. Ma da dove hai trovato questa V985??
Cmq, provi continuita' tra pin uart e jumper R7.
Ho già misurato tra PDN_UART e connettore si c'è continuità e resistenza praticamente nulla.
Ah ho comprato i moduli a poco su aliexpress a pochi €. Mi sembravano tutti uguali e più o meno lo stesso prezzo sinceramente...



