Programmes qui fonctionne sous arduino uno mais réaction bizarre sur attiny44

Bonjour

je viens solliciter votre aide car la je sèche j'ai réaliser ce programme sur arduino uno qui fonctionne très bien seulement voila kan je le porte sur attiny 44 il ce met à déconner sans comprendre pourquoi les relais ce recoupe quasiment aussi tôt leur allumage alors qu'il devrais rester 6 secondes allumé
une idée du problème?

unsigned long previousmillis;
const unsigned long TEMPS_BARRIERE = 6000;


#define S1 5   //pin9
#define S2 4  // pin 8
#define R1 7  //pin
#define R2 6  //pin

void setup() {

  //The pins set up to serve as Digital output pins for LED's
  //Serial.begin(9600);
  pinMode(A0, INPUT);
  pinMode(S1, INPUT);
  pinMode(S2, INPUT);
  pinMode(R1, OUTPUT);
  pinMode(R2, OUTPUT);
}

void loop() {

  if ((digitalRead(R1) == HIGH) or (digitalRead(R2) == HIGH))
  {
    float average = 0;
    average = average + (.049 * analogRead(A0) - 25); // for 20A mode
    //  Serial.println(average);
    delay(100);

    if (millis() - previousmillis >= TEMPS_BARRIERE)
    {
      digitalWrite(R1, LOW);
      digitalWrite(R2, LOW);
    }

    if ((digitalRead(R1) == HIGH) and (digitalRead(S2) == LOW))
    {
      digitalWrite(R1, LOW);
      digitalWrite(R2, HIGH);
      previousmillis = millis();
      delay(1000);
    }

    else  if ((digitalRead(R2) == HIGH) and (digitalRead(S1) == LOW))
    {
      digitalWrite(R2, LOW);
      digitalWrite(R1, HIGH);
      previousmillis = millis();
      delay(1000);
    }


    if ((digitalRead(S1) == LOW) and (digitalRead(R1) == HIGH)) //arrêt après deuxieme appuis S1
    {
      digitalWrite(R1, LOW);
      delay(2000);
    }


    else if ((digitalRead(S2) == LOW) and (digitalRead(R2) == HIGH)) //arrêt après deuxieme appuis S2
    {
      digitalWrite(R2, LOW);
      delay(2000);
    }


    if (average >= 3.00)
    {
      digitalWrite(R1, LOW);
      digitalWrite(R2, LOW);
    }
    else if (average <= -3.00)
    {
      digitalWrite(R2, LOW);
      digitalWrite(R1, LOW);
    }
  }
  else
  {
    if (digitalRead(S2) == LOW) //Sens Rotation
    {
      digitalWrite(R2, HIGH);
      previousmillis = millis();
      delay(1000);
    }
    else if (digitalRead(S1) == LOW) //Sens Anti-Rotation
    {
      digitalWrite(R1, HIGH);
      previousmillis = millis();
      delay(1000);
    }
  }
}

Tu lis les valeurs des sorties? Tu as défini S1 et S2 en entrée et R1 et R2 en sortie. Mais tu écris digitalRead (R1)...

Avec les Attiny85 j'ai déjà eu des problèmes avec les horloges internes et externes. Tu peux vérifier ça en chargeant le programme blink, et en vérifiant qu'il clignote une fois par seconde

Bonjour,

Si ton programme fonctionne sur une uno, il n'y a pas de raison qu'il ne fonctionne pas sur un attiny44 (si il n'y a pas d'erreur dans l'affctation des pins).
D'après la description de ton problème ça fait penser à un problème de parasites. Est ce que le problème se produit quand il n'y a pas de moteur? Quel est le circuit qui commande les relais?

Fantoche:
Tu lis les valeurs des sorties? Tu as défini S1 et S2 en entrée et R1 et R2 en sortie. Mais tu écris digitalRead (R1)...

Avec les Attiny85 j'ai déjà eu des problèmes avec les horloges internes et externes. Tu peux vérifier ça en chargeant le programme blink, et en vérifiant qu'il clignote une fois par seconde

effectivement il semblerais qu'il y un probleme d'horloge la led ne clignote pas du tout quel serais la solution utilisez une horloge externe?

Si l'horloge ne fonctionnait pas tu ne pourrais pas charger le programme.
Tu es sur que la led est sur la bonne pin?

non effectivement il est tard et je me suis mi sur le numéro du pin(12) au lieu de 1 et la led clignote environ une fois par seconde

kamill:
Bonjour,

Si ton programme fonctionne sur une uno, il n'y a pas de raison qu'il ne fonctionne pas sur un attiny44 (si il n'y a pas d'erreur dans l'affctation des pins).
D'après la description de ton problème ça fait penser à un problème de parasites. Est ce que le problème se produit quand il n'y a pas de moteur? Quel est le circuit qui commande les relais?

sur ce premier point on est bien d'accord, les pins sont les bon car vérifier et revérifier, sinon je ne pense pas que ce soit un probleme de parasite car avec ou sans charge sur les relais le probleme est le même et je ne vois pas pourquoi des parasite viendrais perturber un circuit aussi simple avec 2 relais 2 transistor 2diode(roue libre) et quelque résistante de plus le tout alimenter via alim stabiliser le circuit de puissance est isoler de façon galvanique et la lecture d’ampérage ce fait via ads712 donc isolation galvanique aussi et lui me sort bien 2.5v sans charge

j'ai donc modifié pas mal mon code et isolé les partie qui pose problème je précise que je suis plus ou moin en environnement de test mon attiny est dans un support temporaire sur la breaboard , sur ma carte final (enfin c'est ce que je croyais) j'ai souder des fil a la place de l'attiny qui vont a la breaboard sur l'attiny(logique)

bref quand l'attiny est branché ça déconne sur le bout de code correspondant à l'asc712 , le relais s'active et puis après c'est 2s de délay il s'éteint anormalement j'ai donc rien changer au programme pris les fils de l'attiny et mis sur exactement les même numero de pin sur l'arduino et la comme par magie tout fonctionne bien j'en profite pour faire un Serial.print sur la valeur de courant le resultat tourne autour de 0.25 donc ma limite étant à 3 ou -3 cela n'a pas lieu de ce déclenché sur l'attiny avez vous une idée de ce qui ce passe

je vous redonne le code modifié

unsigned long previousmillis;
const unsigned long TEMPS_BARRIERE = 6000;
bool etat_moteur_1;
bool etat_moteur_2;

int sensitivity = 100;
int adcValue = 0;
int offsetVoltage = 2500;
double adcVoltage = 0;
double currentValue = 0;

#define S1 2   //pin9
#define S2 3  // pin 8
#define R1 7  //pin
#define R2 6  //pin

void setup() {

  //The pins set up to serve as Digital output pins for LED's
  Serial.begin(9600);
  pinMode(A1, INPUT);
  pinMode(S1, INPUT);
  pinMode(S2, INPUT);
  pinMode(R1, OUTPUT);
  pinMode(R2, OUTPUT);
}

void loop() {

  if ((etat_moteur_1 == HIGH) || (etat_moteur_2 == HIGH))
  {
    adcValue = analogRead(A1);
    adcVoltage = (adcValue / 1024.0) * 5000;
    currentValue = ((adcVoltage - offsetVoltage) / sensitivity);
    Serial.println(currentValue);


    if (millis() - previousmillis >= TEMPS_BARRIERE)
    {
      digitalWrite(R1, LOW);
      digitalWrite(R2, LOW);
      etat_moteur_1 = 0;
      etat_moteur_2 = 0;
    }

    if (etat_moteur_1 == HIGH)
    {
      if (digitalRead(S2) == LOW)
      {
        digitalWrite(R1, LOW);
        etat_moteur_1 = LOW;
        digitalWrite(R2, HIGH);
        etat_moteur_2 = HIGH;
        previousmillis = millis();
        delay(1000);
      }
    }
    else if (etat_moteur_2 == HIGH)
    {
      if (digitalRead(S1) == LOW)
      {
        digitalWrite(R2, LOW);
        etat_moteur_2 = LOW;
        digitalWrite(R1, HIGH);
        etat_moteur_1 = HIGH;
        previousmillis = millis();
        delay(1000);
      }
    }


    if ((digitalRead(S1) == LOW) && (etat_moteur_1 == HIGH)) //arrêt après deuxieme appuis S1
    {
      digitalWrite(R1, LOW);
      etat_moteur_1 = LOW;
      delay(2000);
    }


    else if ((digitalRead(S2) == LOW) && (etat_moteur_2 == HIGH)) //arrêt après deuxieme appuis S2
    {
      digitalWrite(R2, LOW);
      etat_moteur_2 = LOW;
      delay(2000);
    }


    if (currentValue >= 3)
    {
      digitalWrite(R1, LOW);
      digitalWrite(R2, LOW);
      etat_moteur_1 = 0;
      etat_moteur_2 = 0;
    }
    else if (currentValue <= -3)
    {
      digitalWrite(R2, LOW);
      digitalWrite(R1, LOW);
      etat_moteur_1 = 0;
      etat_moteur_2 = 0;
    }
  }
  else
  {
    if (digitalRead(S2) == LOW) //Sens Rotation
    {
      digitalWrite(R2, HIGH);
      previousmillis = millis();
      etat_moteur_2 = HIGH;
      delay(2000);
    }
    else if (digitalRead(S1) == LOW) //Sens Anti-Rotation
    {
      digitalWrite(R1, HIGH);
      previousmillis = millis();
      etat_moteur_1 = HIGH;
      delay(2000);
    }
  }
}

et la partie qui créer l’arrêt du relais est celle ci

  if (currentValue >= 3)
    {
      digitalWrite(R1, LOW);
      digitalWrite(R2, LOW);
      etat_moteur_1 = 0;
      etat_moteur_2 = 0;
    }
    else if (currentValue <= -3)
    {
      digitalWrite(R2, LOW);
      digitalWrite(R1, LOW);
      etat_moteur_1 = 0;
      etat_moteur_2 = 0;
    }

poezeadri:
et la partie qui créer l’arrêt du relais est celle ci
...

Il y a aussi celle ci:

    if (millis() - previousmillis >= TEMPS_BARRIERE)
    {
      digitalWrite(R1, LOW);
      digitalWrite(R2, LOW);
      etat_moteur_1 = 0;
      etat_moteur_2 = 0;
    }

et celle ci:

    if ((digitalRead(S1) == LOW) && (etat_moteur_1 == HIGH)) //arrêt après deuxieme appuis S1
    {
      digitalWrite(R1, LOW);
      etat_moteur_1 = LOW;
      delay(2000);
    }


    else if ((digitalRead(S2) == LOW) && (etat_moteur_2 == HIGH)) //arrêt après deuxieme appuis S2
    {
      digitalWrite(R2, LOW);
      etat_moteur_2 = LOW;
      delay(2000);
    }

C'est quoi S1 et S2? Des boutons? Ils ont bien des résistances de pullup.

kamill:
Il y a aussi celle ci:

C'est quoi S1 et S2? Des boutons? Ils ont bien des résistances de pullup.

oui mais en enlevant ce morceau de code le reste du code fonctionne comme voulue S1 et S2 sont des signaux arrivant d'un module rf et oui ils ont bien des résistance de pullup

je vous fourni le schéma du montage, S1 et S2 sont les signaux des relay en haut à gauche eu même relié à des relay relié au GND(pas sur le schema)

bon j'ai trouver l'origine de mon problème j'alimente le montage en 5v (c'est une contrainte technique car monté sur une batterie de 6v avec recharges solaire) j'ai donc mis un régulateur de tension ncp1117-5 le problème j'alimente en 5v via alim stabiliser et a la sortie du régulateur je n'est plus que 4V ce qui je pense doit décaler les tension de référence de l'attiny et si mon raisonnement est bon 4v au lieu 5 / 2 puisque la tension de sortie de l'asc712 et de 2.5v à 0 (100mv/A) mais un voltage de reférence de 4V pour l'attiny ce qui fait 0.5v de différence soit 5a et la je dépasse donc ma valeur de 3A de mon programme êtes vous d'accord avec moi? si oui une idée pour palier au problème?

Bonjuour,
à 0A, la tension de sortie de l'asc712 est de Vcc x 0.5 = ... ça dépend de Vcc

trimarco232:
Bonjuour,
à 0A, la tension de sortie de l'asc712 est de Vcc x 0.5 = ... ça dépend de Vcc

même sous 4V l'asc712 me donne 2.5v à 0 ampère

Je viens de faire l'essai, l'ASC712 donne bien la moitié de la tension d'alimentation à 0A.

Tu as mesuré 2.5V comment? Si c'est avec l'adc de l'attiny, c'est normal car comme la tension de référence est la même que la tension d'alimentation de l'ADC712, tu vas trouver la moitié du nombre de pas max.

kamill:
Je viens de faire l'essai, l'ASC712 donne bien la moitié de la tension d'alimentation à 0A.

Tu as mesuré 2.5V comment? Si c'est avec l'adc de l'attiny, c'est normal car comme la tension de référence est la même que la tension d'alimentation de l'ADC712, tu vas trouver la moitié du nombre de pas max.

Non au voltmètre mais je vais revérifier tout ça
mais sinon si je suis donc votre logique il me suffirait de faire une lecture de tension en sortie de régulateur avec un pin analogique de l'attiny et de m'en servir pour définir
int offsetVoltage = analogRead((pin de lecture de tension) / 1024.0) * 5000;

Non, puisque la sortie du régulateur est l’alimentation de l'attiny et la tension de référence, tu vas toujours lire 1023 quelle que soit la tension en sortie du régulateur, donc toujours lire 5V avec ta formule.

kamill:
Non, puisque la sortie du régulateur est l’alimentation de l'attiny et la tension de référence, tu vas toujours lire 1023 quelle que soit la tension en sortie du régulateur, donc toujours lire 5V avec ta formule.

Ok j'ai fais quelques recherche et je viens de tomber sur un tuto sur carnetdumaker ou ils ce sert de la référence interne de 1.1V ils propose ce code mais n'étant pas un expert en registre pour pas dire que je n'y connais rien je sais pas si celui si est susceptible de fonctionner sur attiny

/** Mesure la référence interne à 1.1 volts */
unsigned int analogReadReference(void) {
  
  /* Elimine toutes charges résiduelles */
  ADMUX = 0x4F;
  delayMicroseconds(5);
  
  /* Sélectionne la référence interne à 1.1 volts comme point de mesure, avec comme limite haute VCC */
  ADMUX = 0x4E;
  delayMicroseconds(200);
  
  /* Active le convertisseur analogique -> numérique */
  ADCSRA |= (1 << ADEN);
  
  /* Lance une conversion analogique -> numérique */
  ADCSRA |= (1 << ADSC);
  
  /* Attend la fin de la conversion */
  while(ADCSRA & (1 << ADSC));
  
  /* Récupère le résultat de la conversion */
  return ADCL | (ADCH << 8);
}

/* Fonction loop() */
void loop() {
  float tension_alim = (1023 * 1.1) / analogReadReference();
  delay(1000);
}

cela me permettrais d'avoir une tension connu et donc de faire mes calcul en fonction par contre il marqué qu'il ne faut rien connecter sur la broche aref si j'ai bien compris je vais donc arrêter de l'utiliser

ps: Si vous aviez des liens, cours, tuto qui me permettrais d'en apprendre un peu plus sur les registres et surtout apprendre à les maitriser

Ton programme ne me parait pas adapté à un attiny44.