Go Down

Topic: Optimizing code on arduino due (Read 631 times) previous topic - next topic

lucian_v

Hi all,

I work on o project using an arduino due. So far the premises of the project are:

1 - Arduino connecting to a mqtt server (mosquitto) which is running on a centos pc. For network on arduino I am using W5100 ethernet card.

2 - Arduino read 12 load cells using HX711 chips (one for each load cell). HX711 are modified by lift pin 15 and solder it to vcc for get ability to read at 80Hz (according to manual).

3 - Arduino read the status of 2 push buttons.

4 - Arduino read 2 hall sensors for measuring 2 rpm's.

5 - Arduino subscribe to a mqtt topic where can receive commands for control a 8 relay board (only 5 used now) and also receive command for doing "tare" function on HX711 chips .

Here is the code I am using for all of this.

L.E. - seems i exceed 9000 chars on the message so I will put the code in next message


Now I have few questions if anyone is able to help me:

1 - From time to time rpms and rpmd are getting "inf" value for couple of seconds and then get back to normal. Why is that happen ?

2 - Also in the actual version of the code, if I stop the wheel suddenly at 100 rpm, then the value that arduino sends for rpm don t get to 0 but is still sending that 100 rpm value. How can I fix that?

3 - On that version of code I am using a different topic for publish values. Would be better to use 1 topic for publish all values, something like "value1 / value2 / value3 ..etc" and split them on the other side back?

4 - Do you have some advice for optimize this code ?

If you consider wiring schematic is necessary I will draw it and upload.

Thank you very much


lucian_v

CODE from previous message


Code: [Select]

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include "HX711.h"

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 5, 2);
byte MQTT_SERVER[] = {192,168,5,1};

EthernetClient ethClient;
PubSubClient client;

char send_data_char[128];
char send_data_char_vs[128];
char send_data_char_vd[128];
char send_data_char_gs[128];
char send_data_char_gd[128];
char send_data_char_fs[128];
char send_data_char_fd[128];

volatile int rpmcounts = 0;
volatile int rpmcountd = 0;

float times0, times01, times2=0, rpms=0;
float timed0, timed01, timed2=0, rpmd=0;



unsigned long timehx = 100;
int read_hx = 0;
float gs1, gs2, gs3, gs4, gd1, gd2, gd3, gd4, fs, fd, ps1, ps2, GS, GD;
String send_data;
String send_data_vs;
String send_data_vd;
String send_data_gs;
String send_data_gd;
String send_data_fs;
String send_data_fd;

HX711 s01(22, 23);  // gs1 // (dt, clk)
HX711 s02(24, 25);  // gs2 // (dt, clk)
HX711 s03(26, 27);  // gs3 // (dt, clk)
HX711 s04(28, 29);  // gs4 // (dt, clk)

HX711 s05(30, 31);  // gd1 // (dt, clk)
HX711 s06(32, 33);  // gd2 // (dt, clk)
HX711 s07(34, 35);  // gd3 // (dt, clk)
HX711 s08(36, 37);  // gd4 // (dt, clk)

HX711 s09(38, 39);  // fs // (dt, clk)
HX711 s10(40, 41);  // fd // (dt, clk)

//HX711 s11(42, 43);  // ps1 // (dt, clk)
//HX711 s12(44, 45);  // ps2 // (dt, clk)

int R1 = 46;
int R2 = 47;
int R3 = 48;
int R4 = 49;
int R5 = 5;

const int prezs_pin = 14;
const int prezd_pin = 15;

int prezs = 0, prezd = 0;

void setup() {
 // Serial.begin(9600);
 // Serial.println("START");

  pinMode(R1, OUTPUT);
  digitalWrite(R1, HIGH); // R1 OFF
  pinMode(R2, OUTPUT);
  digitalWrite(R2, HIGH); // R2 OFF
  pinMode(R3, OUTPUT);
  digitalWrite(R3, HIGH); // R3 OFF
  pinMode(R4, OUTPUT);
  digitalWrite(R4, HIGH); // R4 OFF
  pinMode(R5, OUTPUT);
  digitalWrite(R5, HIGH); // R5 OFF
  
  s01.set_scale(2500);       //calib gs2
  s01.tare();            
  s02.set_scale(2500);       //calib gs2
  s02.tare();
  s03.set_scale(2500);       //calib gs3
  s03.tare();
  s04.set_scale(2500);       //calib gs4
  s04.tare();

  s05.set_scale(2500);       //calib gd1
  s05.tare();
  s06.set_scale(2500);       //calib gd2
  s06.tare();
  s07.set_scale(2500);       //calib gd3
  s07.tare();
  s08.set_scale(2500);       //calib gd4
  s08.tare();

  s09.set_scale(2500);       //calib fs
  s09.tare();
  s10.set_scale(2500);       //calib fd
  s10.tare();

//  s11.set_scale(2500);       //calib ps1
//  s11.tare();
//  s12.set_scale(2500);       //calib ps2
//  s12.tare();

  Ethernet.begin(mac, ip);
  client  = PubSubClient(MQTT_SERVER, 1883, callback, ethClient);


//  Serial.print("Network ip : ");
//  Serial.println(Ethernet.localIP());

pinMode(prezs_pin, INPUT);
pinMode(prezd_pin, INPUT);

attachInterrupt(2, hallSensors, RISING);//interrupt 0 is on pin 2.
attachInterrupt(3, hallSensord, RISING);//interrupt 1 is on pin 3.

}

void loop() {

  if (!client.connected())  {
    client.connect("std_vs");
    client.connect("std_vd");
    client.connect("std_gs");
    client.connect("std_gd");
    client.connect("std_fs");
    client.connect("std_fd");
    client.subscribe("stdin");
      }
  
  read_hx++;
  if (read_hx == 1){
      timehx = millis();
  }
  if (millis() - timehx >= 100){
  
    send_data_vs = String(rpms);
    send_data_vs.toCharArray(send_data_char_vs, send_data_vs.length() + 1);
    client.publish("std_vs", send_data_char_vs);
    
    send_data_vd = String(rpmd);
    send_data_vd.toCharArray(send_data_char_vd, send_data_vd.length() + 1);
    client.publish("std_vd", send_data_char_vd);

    send_data_gs = String(GS);
    send_data_gs.toCharArray(send_data_char_gs, send_data_gs.length() + 1);
    client.publish("std_gs", send_data_char_gs);

    send_data_gd = String(GD);
    send_data_gd.toCharArray(send_data_char_gd, send_data_gd.length() + 1);
    client.publish("std_gd", send_data_char_gd);

    send_data_fs = String(fs);
    send_data_fs.toCharArray(send_data_char_fs, send_data_fs.length() + 1);
    client.publish("std_fs", send_data_char_fs);

    send_data_fd = String(fd);
    send_data_fd.toCharArray(send_data_char_fd, send_data_fd.length() + 1);
    client.publish("std_fd", send_data_char_fd);
  
    read_hx = 0;
  }

  readhx();
  
  read_prezs();
  read_prezd();
  
  client.loop();
}

void readhx(){

  gs1 = s01.get_units(3);
  gs2 = s02.get_units(3);
  gs3 = s03.get_units(3);
  gs4 = s04.get_units(3);
  GS = gs1 + gs2 + gs3 + gs4;
  
  
  gd1 = s05.get_units(3);
  gd2 = s06.get_units(3);
  gd3 = s07.get_units(3);
  gd4 = s08.get_units(3);
  GD = gd1 + gd2 + gd3 + gd4;


  fs = s09.get_units(3);
  fd = s10.get_units(3);

//    ps1 = s11.get_units();
//    ps2 = s12.get_units();

}

void startR1() {
  digitalWrite(R1, LOW);
}

void startR2() {
  digitalWrite(R2, LOW);
}

void startR3() {
  digitalWrite(R3, LOW);
}

void startR4() {
  digitalWrite(R4, LOW);
}

void startR5() {
  digitalWrite(R5, LOW);
}

void stopR1() {
  digitalWrite(R1, HIGH);
}

void stopR2() {
  digitalWrite(R2, HIGH);
}

void stopR3() {
  digitalWrite(R3, HIGH);
}

void stopR4() {
  digitalWrite(R4, HIGH);
}

void stopR5() {
  digitalWrite(R5, HIGH);
}

void read_prezs(){
  prezs = digitalRead(prezs_pin);
  if (prezs == HIGH){
    prezs = 1;
  }else{
    prezs = 0;
  }
}

void read_prezd(){
  prezd = digitalRead(prezd_pin);
  if (prezd == HIGH){
    prezd = 1;
  }else{
    prezd = 0;
  }
}

void hallSensors(){

 rpmcounts++;
 if (rpmcounts == 1){
   times01 = millis();
 }
 if (rpmcounts == 2){
   times2 = millis() - times01;
   rpms = (1 / (times2 / 1000) * 60);
  
   rpmcounts=0;  
 }
}

void hallSensord(){
  rpmcountd++;
  if (rpmcountd == 1){
    timed01 = millis();
  }
  if (rpmcountd == 2){
    timed2 = millis() - timed01;
    rpmd = (1 / (timed2 / 1000) * 60);

    rpmcountd=0;  
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
    
  if (String((char)payload[0]) == "R") {
      if ((char)payload[1] == '1') {
          if ((char)payload[2] == '1') {
              startR1();
          }
          else if ((char)payload[2] == '0') {
              stopR1();
          }
    }
    else if ((char)payload[1] == '2') {
          if ((char)payload[2] == '1') {
              startR2();
          }
          else if ((char)payload[2] == '0') {
              stopR2();
          }
    }
    else if ((char)payload[1] == '3') {
          if ((char)payload[2] == '1') {
              startR3();
          }
          else if ((char)payload[2] == '0') {
              stopR3();
          }
    }
    else if ((char)payload[1] == '4') {
          if ((char)payload[2] == '1') {
              startR4();
          }
          else if ((char)payload[2] == '0') {
              stopR4();
          }
    }
    else if ((char)payload[1] == '5') {
          if ((char)payload[2] == '1') {
              startR5();
          }
          else if ((char)payload[2] == '0') {
              stopR5();
          }
  
   }
  else if (String((char)payload[0]) == "T") {
      if ((char)payload[1] == '1') {  // tare st
            s01.tare();            
            s02.tare();
            s03.tare();
            s04.tare();
      }
      else if ((char)payload[1] == '2') {  //tare dr
            s05.tare();
            s06.tare();
            s07.tare();
            s08.tare();
      }
      else if ((char)payload[1] == '3') {  //tare FS / FD
            s09.tare();
            s10.tare();
      }
//      else if ((char)payload[1] == '4') {  //tare Pres1
//            s11.tare();
//      }
//      else if ((char)payload[1] == '5') {  //tare Pres2
//            s12.tare();
//      }
        
  }
  
  }
}



lucian_v

Related to Q1: Noticed that when I get "inf" actually timed2 /times2 is 0 ....don t know why it becomes 0

PaulS

The first step in optimizing the code is to start over. Before you do that, though. Read up on arrays.

The second step is to COMPLETELY ditch the String class. There is no excuse for being so lazy.

There is NO excuse for having 5 functions to turn a pin on and 5 more to turn a pin off. That can be done with ONE function that takes a pin number and a state. There are not 54 functions to read the 54 digital pins on a Due. Don't write your code that way.

Code: [Select]
  if (prezs == HIGH){
    prezs = 1;
  }else{
    prezs = 0;
  }

That's stupid. If the value is 1 (that's the value associated with the name HIGH), make it 1. Otherwise, make the value 0 (which is what it already was).

Code: [Select]
  if (String((char)payload[0]) == "R") {
Completely asinine.
Code: [Select]
   if(payload[0] == 'R')
   {


You got most of the rest of them right (except the unnecessary cast). Why did you f**k that one (and a few others) up?

Quote
1 - From time to time rpms and rpmd are getting "inf" value for couple of seconds and then get back to normal. Why is that happen ?
What is 1/0? It's undefined, but generally accepted to be infinity.

Quote
2 - Also in the actual version of the code, if I stop the wheel suddenly at 100 rpm, then the value that arduino sends for rpm don t get to 0 but is still sending that 100 rpm value. How can I fix that?
When you stop the wheel, interrupts stop happening. You need to pay attention to how long it has been since an interrupt happened. Which means that in the ISR is the wrong place to be calculating RPM. ALL that the ISR should do is increment a counter.

Code: [Select]
float times0, times01, times2=0, rpms=0;
float timed0, timed01, timed2=0, rpmd=0;

Times are NOT floats.
The art of getting good answers lies in asking good questions.

lucian_v

@PaulS - Thanks a lot for your explanations. I admit I didn't understand everything you wrote, probably because I am quite beginner but I do my best to rewrite the code following your indications.

I will take it again step by step since I discovered some other issues. I will post here when do something.

Thanks a lot again, I really appreciate .

Go Up