BaroneRosso.it - Forum Modellismo

BaroneRosso.it - Forum Modellismo (https://www.baronerosso.it/forum/)
-   Circuiti Elettronici (https://www.baronerosso.it/forum/circuiti-elettronici/)
-   -   switch ppm con Arduino, possibile? (https://www.baronerosso.it/forum/circuiti-elettronici/328619-switch-ppm-con-arduino-possibile.html)

dannybon 23 novembre 14 20:32

si lo intuivo, ho postato anche sul forum di arduino la stessa domanda ma li ancora non rispondono.
Continuerò a studiare..

CarloRoma63 26 novembre 14 16:16

Citazione:

Originalmente inviato da dannybon (Messaggio 4458280)
Buongiorno
Allora..... Ho ripreso in mano il libro di arduino e ho ricominciato a dare una lettura.
Ho scritto uno sketch sicuramente sbagliato ma devo pur cominciare......
Quello che m'interessa al momento è sapere se il concetto scritto è giusto, non m'interessa sapere se è correttamente scritto o se funzionera'.
Questo è quanto scritto:

int ch1 = 1;
int ch2 = 2;
int ch3 = 3;
int ch4 = 4;
int ch8 = 5;
int ch1(2) = 6;
int ch2(2) = 7;
int ch3(2) = 8;
int ch4(2) = 9;
int ch1(3) = 10;
int ch2(3) = 11;
int ch3(3) = 12;
int ch4(3) = 13;
void setup() {

pinMode(ch1, INPUT);
pinMode(ch2, INPUT);
pinMode(ch3, INPUT);
pinMode(ch4, INPUT);
pinMode(ch8, INPUT);
pinMode(ch1(2), OUTPUT);
pinMode(ch2(2), OUTPUT);
pinMode(ch3(2), OUTPUT);
pinMode(ch4(2), OUTPUT);
pinMode(ch1(3), OUTPUT);
pinMode(ch2(3), OUTPUT);
pinMode(ch3(3), OUTPUT);
pinMode(ch4(3), OUTPUT);

}

void loop() {
// read the value from the sensor:
ch1 = analogRead(ch1);
ch2 = analogRead(ch2);
ch3 = analogRead(ch3);
ch4 = analogRead(ch4);
ch8 = analogRead(ch8);
if
ch8= LOW
digitalWrite(ch1(2), Valore letto da ch1 );
digitalWrite(ch2(2), valore letto da ch2 );
digitalWrite(ch3(2), valore letto da ch3 );
digitalWrite(ch4(2), valore letto da ch4 );

else
digitalWrite(ch1(3), valore letto da ch1) ;
digitalWrite(ch1(3), valore letto da ch2) ;
digitalWrite(ch1(3), valore letto da ch3) ;
digitalWrite(ch1(3), valore letto da ch4) ;

In pratica sto cercando di dire ad arduino che i 4 canali principali CH1,2,3,4 devono leggere il segnale proveniente dalla rx. Se ch8 ha un segnale basso ( switch radio basso) il segnale deve uscire dalla batteria di canali CH 1,2,3,4 (2) altrimenti uscire dall'altra batteria ch1,2,3,4 (3).

E' la prima volta che scrivo un codice non mi massacrate :D

Concettualmente sembra tutto OK, solo che le funzioni di lettura che hai usato sono ANALOGICHE, leggono quindi la tensione presente su pin, non il tempo per cui è stata ON o OFF. Pur conquesta limitazione, il programma potrebbe quasi funzionare (dovresti sostiuire l'analogRead con la digitalRead e, con la imprecisione data dalla limitazione della velocità di elaborazione, riusciresti a "copiare" in tempo reale gli ingressi sulle uscite) ma non con la gestione del CH8 fatta così.
Per il Ch8 dovresti implementare una routine basata sugli interrupt per leggerne con precisione la durata dell'impulso e, di conseguenza, decidere verso quali uscite copiare gli ingressi.
Qualcosa sia sugli interrupt che sulla lettura del PPM la puoi leggere quì: RCArduino: How To Read RC Receiver PPM Stream

Se tu riuscissi ad accedere all'intero frame PPM anzichè ai singoli canali, allora il codice che ti ho linkato è esattamente quello che ti occorre, dovresti modificarlo solo per la parte di uscita.

Carlo

dannybon 27 novembre 14 17:14

Grazie Carlo.
Ho scritto anche sul forum arduino e mi hanno detto che il codice non ha senso.... é impossibile far fare ad arduino ciò che mi serve.....
Non so che dire, certo non demordo :wink:
PRoverò a studiare di più e leggermi il link da te segnalato, grazie mille ancora.

CarloRoma63 27 novembre 14 17:26

Citazione:

Originalmente inviato da dannybon (Messaggio 4464634)
Grazie Carlo.
Ho scritto anche sul forum arduino e mi hanno detto che il codice non ha senso.... é impossibile far fare ad arduino ciò che mi serve.....
Non so che dire, certo non demordo :wink:
PRoverò a studiare di più e leggermi il link da te segnalato, grazie mille ancora.

Dammi il link della tua discussione sul forum di Arduino.
nel frattempo, se ci riesco e se ho tempo, provo a fare io quello che ti occorre.

Carlo

dannybon 27 novembre 14 17:49

grazie mille carlo.
Questo è il link :

switchare segnali ppm/pcm con arduino

ElNonino 27 novembre 14 17:52

Se ho capito bene vuoi commutare due banchi di 4 servocomandi introducendo un certo ritardo sia nel passaggio banco 1 <-> banco 2.

Per me si potrebbe realizzare con un paio di integrati 'tradizionali' TTL o CMOS + un NE555 senza scomodare microprocessori e firmware vari.

:yeah:

CarloRoma63 27 novembre 14 20:18

Citazione:

Originalmente inviato da CarloRoma63 (Messaggio 4464645)
Dammi il link della tua discussione sul forum di Arduino.
nel frattempo, se ci riesco e se ho tempo, provo a fare io quello che ti occorre.

Carlo

Prova questo. Io non l'ho potuto collaudare perchè in questo momento non ho un servo da collegare. In questa versione commmuta solo il CH1 tra i pin 5 e 6. Il pin ove iniettare il PPM è il 2, se ti funziona basta duplicare la parte di output.

Carlo

Citazione:

#include <RCArduinoFastLib.h>

// MultiChannels
//
// rcarduino.blogspot.com
//
// A simple approach for reading three RC Channels using pin change interrupts
//
// See related posts -
// RCArduino: How To Read an RC Receiver With A Microcontroller - Part 1
// RCArduino: Need More Interrupts To Read More RC Channels ?
// RCArduino: Can I Control More Than X Servos With An Arduino ?
//
// rcarduino.blogspot.com
//


#define SERVO_FRAME_SPACE 5
#define CH_in 5 // questo è il canale che viene testato. La numerazione parte da 0
#define CH1 0 // questo è il canale che viene commmutato
#define CH_out1 5 // questo è il primo pin di uscita a cui inviare il CH1
#define CH_out2 6 // questo è il secondo pin di uscita a cui inviare il CH1

volatile uint32_t ulCounter = 0;

void setup()
{
Serial.begin(115200);


// lets set a standard rate of 50 Hz by setting a frame space of 10 * 2000 = 4 Servos + 6 times 2000
CRCArduinoFastServos::setFrameSpaceA(SERVO_FRAME_S PACE,8*2000);

CRCArduinoFastServos::begin();
CRCArduinoPPMChannels::begin();
}

void loop()
{
uint16_t unThrottleIn = CRCArduinoPPMChannels::getChannel(CH_in);
if(unThrottleIn) // Verifico se ho un segnale PPM valido per il canale 6
{
if(unThrottleIn<1500)
{
CRCArduinoFastServos::attach(CH1,CH_out1);
Serial.print ("1-unThrottleIn:");
Serial.println (unThrottleIn);
}
else
{
CRCArduinoFastServos::attach(CH1,CH_out2);
Serial.print ("2-unThrottleIn:");
Serial.println (unThrottleIn);
}
}

}

ElNonino 27 novembre 14 21:27

Permettetemi una considerazione: usando un microprocessore e relativo firmware può succedere che in caso di impallamento ci si trovi nella situazione che x servo del gruppo 1 ed y servo del gruppo 2 vadano insieme, non conoscendo l'applicazione ed il grado di affidabilità richiesto non so se tale situazione potrebbe creare problemi.

Usando un micro si crea inoltre un ulteriore ritardo sul comando di ogni canale e bisognerebbe valutare se è tollerabile per l'applicazione.

Se il delay della commutazione fosse gestito dalla Tx (molte hanno questa opzione) il circuito si semplificherebbe ulteriormente, poi se si vuole giocare con Arduino va tutto bene, sia chiaro.

IMHO

:yeah:

CarloRoma63 27 novembre 14 22:28

Citazione:

Originalmente inviato da ElNonino (Messaggio 4464916)
Permettetemi una considerazione: usando un microprocessore e relativo firmware può succedere che in caso di impallamento ci si trovi nella situazione che x servo del gruppo 1 ed y servo del gruppo 2 vadano insieme, non conoscendo l'applicazione ed il grado di affidabilità richiesto non so se tale situazione potrebbe creare problemi.

Usando un micro si crea inoltre un ulteriore ritardo sul comando di ogni canale e bisognerebbe valutare se è tollerabile per l'applicazione.

Se il delay della commutazione fosse gestito dalla Tx (molte hanno questa opzione) il circuito si semplificherebbe ulteriormente, poi se si vuole giocare con Arduino va tutto bene, sia chiaro.

IMHO

:yeah:

l'osservazione è corretta, ma forse non si applica al caso in oggetto.
Considerando l'applicazione in questione (un robot terrestre) non credo che ci siano grosse implicazioni di sicurezza, ma su questo dannyboy può essere più preciso.
In ogni modo il codice che ho postato è solo un abbozzo, serve solo a vedere se la metodica può funzionare o, come è stato scritto sul forum di arduino, sarebbe troppo lento per eseguire quel lavoro correttamete. Nulla vieta, se i primi test daranno esito positivo, di migliorarne l'affidabilità.

Carlo

BBC25185 27 novembre 14 23:05

Dunque....
Il codice che hai postato , sotto certi aspetti và bene, sotto altri no....

Tanto per cominciare, l'errore più grande...
Non conosci come funziona il segnale che comanda il servo, vero???
Quindi, siccome bisogna saperlo, leggiti questo:
Come funziona un servocomando | Settorezero
Continuando... Dopo che ti sei letto quello sopra, capisci che il comando "analogRead" non và bene... e, per aiutarti, potrei suggerirti il comando "PulseIn" (però leggilo il sito che ti ho linkato.... altrimenti non capisci nulla)...

Continuando....
Che grado di precisione ti serve ai comando e che velocità di risposta????
Questa domanda và direttamente a influenzare il codice che và scritto perchè lo cambia moltissimo...
Un codice abbastanza semplice e che è molto simile a quello tuo produrra si l'effetto voluto ma si noteranno delle imperfezioni dei comandi (il servo vibra leggermente oppure è scattoso)...
Complicando il codice, invece, si può ottenere l'effetto voluto, ma ti assicuro che è codice abbastanza complesso e, sicuramente, non adeguato all'inizio di chi comincia (che non ci capirebbe nulla)...

Finendo:
Che sicurezza vuoi ai comandi...
Mi spiego... l'arduino è una piattaforma di sviluppo.... non è realizzata per essere una piattaforma stabile....
Dove voglio arrivare??? a quello che è successo a me... che durante la navigazione del sommergibile dove la scheda arduino gestiva la pompa di immersione, si era bloccata (in tilt) a causa di un picco di tensione e mi era rimasta la pompa che caricava in immersione.... puoi immaginarti come ero...
La soluzione è stato un miglior filtraggio dell'alimentazione e, per essere più sicuro, l'implementazione di codice aggiuntivo non descritto sull'arduino per un suo reset automatico...

Per finire, un codice di esempio che dovrebbe funzionare potrebbe essere questo...
Sicuramente non è finito e funzionerà male (non lo ho provato) però dovrebbe dare una idea di come funziona!!!

#include <Servo.h>

#define RX1 1 //Definizioni dei PIN
#define RX2 2 //Ad ogni riga associa il nome al valore che segue
#define RX3 3 //Quindi , per esempio, quando scriverò RX1, l'IDE lo sosituisce con 1
#define RX4 4
#define RX5 5
#define SERVO_A1 6
#define SERVO_A2 7
#define SERVO_A3 8
#define SERVO_A4 9
#define SERVO_B1 10
#define SERVO_B2 11
#define SERVO_B3 12
#define SERVO_B4 13

Servo SERVO_A[4];//Creo 4 variabili chiamate SERVO_A con, all'interno della quadra, il suo identificativo
Servo SERVO_B[4];
int CH[5];

void setup() {
//impostazione degli INPUT della ricevente
pinMode(RX1, INPUT);
pinMode(RX2, INPUT);
pinMode(RX3, INPUT);
pinMode(RX4, INPUT);
pinMode(RX5, INPUT);
//impostazione degli output del primo gruppo
SERVO_A[0].attach(SERVO_A1);
SERVO_A[1].attach(SERVO_A2);
SERVO_A[2].attach(SERVO_A3);
SERVO_A[3].attach(SERVO_A4);
//impostazione degli output del secondo gruppo
for (byte i=SERVO_B1; i<=SERVO_B4; i++){ //Questo fà la stessa cosa delle 4 righe sopra, ma in un modo più elegante
SERVO_B[i-SERVO_B1].attach(i);
}
}

void loop() { //Legge i 5 canali della ricevente....
CH[1] = pulseIn (RX1,HIGH, 30000); //il 30000 sono i uS che aspetta per rilevare il segnale
CH[2] = pulseIn (RX2,HIGH, 30000); //non è un bel sistema di lettura e funziona abbastanza male, ma và benissimo per cominciare
CH[3] = pulseIn (RX3,HIGH, 30000);
CH[4] = pulseIn (RX4,HIGH, 30000);
CH[5] = pulseIn (RX5,HIGH, 30000);
if (CH[5] < 1500) { //Se è inferiore al centro del segnale (1500 è in ms) pilota il primo gruppo
SERVO_A[0].writeMicroseconds(CH[1]);
SERVO_A[1].writeMicroseconds(CH[2]);
SERVO_A[2].writeMicroseconds(CH[3]);
SERVO_A[3].writeMicroseconds(CH[4]);
}
else { //O pilota il secondo gruppo
SERVO_B[0].writeMicroseconds(CH[1]);
SERVO_B[1].writeMicroseconds(CH[2]);
SERVO_B[2].writeMicroseconds(CH[3]);
SERVO_B[3].writeMicroseconds(CH[4]);
}
}


Tutti gli orari sono GMT +2. Adesso sono le 13:36.

Basato su: vBulletin versione 3.8.11
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
E' vietata la riproduzione, anche solo in parte, di contenuti e grafica. Copyright 1998/2019 - K-Bits P.I. 09395831002