Problema comunicazione seriale-bluetooth

Buonasera a tutti,
sto facendo debugging su un codice per il pilotaggio di un automodello comandato tramite bluetooth. il programma compila ma non viene caricato sull'arduino per il seguente errore:
ser_open(): can't open device ".\COM4": Accesso negato. Il programma senza l'utilizzo di Serial.begin viene caricato sull'arduino.

#include<SoftwareSerial.h>

//Pin
int servopwm = 11;
int servodir = 12;
int pinRx = A1;
int pinTx = A2;
int potref = A0;
int motorpwm = 9;
int motordir = 8;
int interruptPin = 3;

SoftwareSerial bluetooth(pinRx,pinTx);

//Variabili sistema di controllo servo
float servomotorvalue;
float degree;
float mydegree;
float servoerror;
char op; //operation
float K=8; //guadagno controllore proporzionale servo
const float MaxSteeringAngle = 20; //angolo max sterzata
const float MinSteeringAngle = -20; //angolo min sterzata
const float MinAnalogRef = 393; //valore min potenziometro
const float MaxAnalogRef = 614; //valore max potenziometro
const float minpwm = 15;
float offset;
const float max_offset = 6.00; //offset angolo

//Filtro a media mobile servo
int const servofsize = 30; //grandezza vettore filtro
float servofilter[servofsize];
int i=0;
float servoavg = 0.0; //average

//Variabili lettura mocoder
const float Diffteeth = 44.00;
const float Mocoteeth = 33.00;
const float gr = 1.333; //gears ratio (diffteeh/mocoteeth)

volatile unsigned long count;
unsigned long oldcount = 0;
unsigned long t1,dt;
const long interval = 500; //milliseconds
float ve; //velocita' encoder
float v; //velocita' macchina
const float wheelray = 1.10; //cm, raggio = 11mm
const float wheelcircumference = (2*3.14*wheelray);
unsigned long iter = 1;

void isr(){
  count++;
}

const float max_pwm = 255.00;

//Filtro a media mobile mocoder
int const motorfsize = 5;
float motorfilter[motorfsize];
int i1=0;
float motoravg = 0.0; //average

//Variabili controllore PI
float myv;
float motorerror;
float Kp = 10;
float Ki = 1;
float integer = 0.0;
float motorvalue;
float m = pow(10,-3);

void setup(){
 pinMode(pinRx,INPUT);
 pinMode(pinTx,OUTPUT);
 pinMode(servopwm,OUTPUT);
 pinMode(servodir,OUTPUT);
 pinMode(potref,INPUT);
 pinMode(motorpwm,OUTPUT);
 pinMode(motordir,OUTPUT);
 pinMode(interruptPin,INPUT);
 attachInterrupt(digitalPinToInterrupt(interruptPin),isr,RISING);
 bluetooth.begin(115200);
 Serial.begin(9600);
}

void loop(){
 ReadBT();
 ControlloServo();
 ControlloMotore();
}

//Motore
void Stop(){
  digitalWrite(servopwm,LOW);
}

void ControlloServo(){
  degree = Map() + Offset();
  servoerror = mydegree - degree;
  servomotorvalue = abs((K * servoerror));
  if(servomotorvalue < minpwm){
    Stop();
    Serial.println("Fine sterzata");
  }else if(degree < mydegree){
    digitalWrite(servodir,HIGH); //gira a destra
    analogWrite(servopwm,servomotorvalue);
    Serial.println("Sterzo a destra di:");
    Serial.println(degree);
  }else if(degree > mydegree){
    digitalWrite(servodir,LOW); //gira a sinistra
    analogWrite(servopwm,servomotorvalue);
    Serial.println("Sterzo a sinistra di:");
    Serial.println(degree);
  }
}

float ServoAverage(){ //media mobile
  int s = analogRead(potref);
  servofilter[i] = s;
  if(i < (servofsize - 1)) i++;
  else i = 0;
  servoavg = 0.0;
  for(int j=0; j<servofsize; j++){
    servoavg += (float)servofilter[j];
  }
  return servoavg = servoavg/(float)(servofsize);
}

float Offset(){
  return offset = motorvalue*max_offset/max_pwm;
}

float Map(){
  return degree = ((ServoAverage()-MinAnalogRef)*(MaxSteeringAngle-MinSteeringAngle)/(MaxAnalogRef-MinAnalogRef)+MinSteeringAngle);
}

void ReadBT(){
  
  if(bluetooth.available()){
    op = bluetooth.read();
    if(op == 's'){
      Serial.println("Hai inserito:");
      Serial.println(op);
      mydegree = bluetooth.parseFloat();
    }
    if(op == 'f'){
      Serial.println("Hai inserito:");
      Serial.println(op);
      digitalWrite(motordir,HIGH);
      myv = bluetooth.parseFloat();
      integer = 0;
    }
    else if(op == 'r'){
      Serial.println("Hai inserito:");
      Serial.println(op);
      digitalWrite(motordir,LOW);
      myv = bluetooth.parseFloat();
      integer = 0;
    }
  }
}

void Run(float motorvalue){
  analogWrite(motorpwm,motorvalue);
  Serial.println("Motore in funzione");
}

float Velocity(){
  dt=millis()-t1;
  if(dt>=interval){
    t1=millis();
    detachInterrupt(digitalPinToInterrupt(interruptPin));
    ve = (float)(count-oldcount)/(float)(interval);
    v = ve*gr*wheelcircumference; //cm/s
    oldcount = count;
    attachInterrupt(digitalPinToInterrupt(interruptPin),isr,RISING);
  }
  return v;
}

float MotorAverage(){ //Media mobile velocita'
  motorfilter[i1] = v;
  if(i1<(motorfsize-1)) i1++;
  else i1 = 0;
  motoravg = 0.0;
  for(int j1=0; j1<motorfsize; j1++){
    motoravg += motorfilter[j1];
  }
  return motoravg = motoravg/(float)(motorfsize);
}

void ControlloMotore(){ //Controllo Proporzionale Integrale
  Velocity();
  MotorAverage();
  motorerror = myv - motoravg;
  motorvalue = Kp*motorerror + integer;
  integer = Ki*(integer + (motorerror*(interval*m)));
  motorvalue = constrain(motorvalue,0,max_pwm);
  Run(motorvalue);
}

:warning:
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato. Grazie.

A quanto detto da UKHeliBob aggiungo ...

... cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento, fai la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Detto questo, come richiesto al punto 7 del succitato regolamento, per favore edita il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone a forma di piccola matita :pencil2: che si trova in basso del tuo post), seleziona la parte di codice e premi l'icona </> nella barra degli strumenti per contrassegnarla come codice. Inoltre, così com'è, non è molto leggibile ... assicurati di averlo correttamente indentato nell'IDE prima di inserirlo (questo lo si fa premendo ctrlT su un PC o cmd T su un Mac, sempre all'interno del IDE).

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione e sistemato il codice come indicato, nel rispetto del regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

Se ho ben capito, se nel setup() tu metti la Serial.begin() NON riesci a caricare il programma su Arduino perché, l'IDE, in fase di caricamento non trova la COM4: e quindi il bootloader fallisce l'upload del codice nella flash della MCU, se invece tu non metti la Serial.begin() nel setup(), il caricamento avviene regolarmete ed i programma parte ... è così ?

Perché è cosa molto strana dato che, in fase di caricamento, il bootloader ed il PC non sanno ed ignorano cosa c'è nel .HEX che viene caricato e quindi ... come fa il PC a dare che la porta è occupata o meno ?

Sicuro che l'errore non avvenga DOPO che il programma è stato caricato in flash, quando viene messo in esecuzione ?

Dicci su che modello di Arduino stai caricando il programma e metti le ultime righe della compilazione/caricamento così vediamo l'errore esatto che viene indicato nell'IDE (prima di compilare, vai nelle preferenze dell'IDE e metti il segno di spunta ai dettagli sia in fase di compilazione che in fase di caricamento, così i messaggi di errore saranno più completi).

Guglielmo

ciao

intanto prova a mettere i i begin() all inizio
io per una applicazione ho risolto cosi'

quote="mattep99, post:1, topic:1060283"]

 bluetooth.begin(115200);
 Serial.begin(9600);

[/quote]

@mattep99: Ah ... un altra cosa ... è ampiamente dimostrato (ci sono vari thread che ne parlano) che oltre i 38400 la SoftwareSerial dia dei problemi (errori vari in ricezione) quindi ti sconsiglio caldamente di usarla a 115200 ... al limite, per raggiungere certe velocità, puoi usare la AltSoftSerial, estremamente più performante ... unico limite, ha dei pin fissi che è obbligatorio utilzzare.

Guglielmo

Buongiorno, anzitutto mi scuso per gli errori in fase di composizione dell'argomento, essendo il primo post non ho controllato bene il regolamento e vi ringrazio per i suggerimenti. Penso di aver anche sbagliato termine: il programma viene compilato ma non eseguito, carico l'ultima linea di esecuzione come richiesto. Sto utilizzando un Arduino Nano.

Che sistema operativo usi.
Sei sicuro che il tuo arduino sia connesso a COM4?

Arduino Nano è basato su ATmega328P quindi è come Arduino UNO ... NON è possibile che quell'errore lo dia solo se non c'è quella riga nel codice ... a quel livello (avrdude) non interessa cosa c'è nel .HEX, ma solo la sua dimensione, e ... quella sembra a posto.

Alle domande che ti ha fatto qua sopra Arco_500 aggiungo ... ci sono antivirus in esecuzione? Hai qualche emulatore seriale che tiene aperta la COM4:?

Guglielmo

Ho Windows 10.Si, arduino è connesso a COM4, ho caricato ed eseguito correttamente il programma eliminando la parte di codice che riguarda la parte seriale. Ho anche caricato ed eseguito il programma aggiungendo la parte seriale e inizialmente mi ha stampato correttamente sul display il primo messaggio poi, aggiungendo altri messaggi e provando a ricaricare il programma mi appare lo stesso errore.

L'antivirus non è in esecuzione e la porta non è occupata da emulatori.

Questo è l'errore che compare ora che ho attivato la "verbose"

Ripeto, è un problema che nulla ha a che vedere con il codice ... "avrdude", che è il programma (richiamato in background dal IDE) che ti manda quei messaggi, NON sa cosa c'è nel codice e, in quella fase, probabilmente neanche ha ancora aperto il .HEX che poi dovrà trasmettere al bootloader ... è un problema a basso livello che riguarda la COM4: ... :roll_eyes:

Io lavoro su macOS quindi ... di più per Win10 non so dirti ...

Guglielmo

... mmm ... ricordavo in passato, ed ho trovato, un problema simile al tuo ... leggi QUESTO thread.

Guglielmo