SOLVED, make code run faster

Hello,

so for my first project i think the code turned out relatively good, but, I would like to know if there is any possible way to make it run faster, so for example the diplay updates faster.

here is my code:

#include "SSD1306Ascii.h"                                   //include oled libray
#include "SSD1306AsciiAvrI2c.h"                             //faster AVR i2c library     
#include "HX711.h"                                          //HX711 load-cell-amplifier library

#define DOUT  3                                             //pin on arduino to wich the digital pin of the HX711 amplifier is conected 
#define CLK  2                                              //pin on arduino to wich the clock pin of the HX711 amplifier is conected 
HX711 scale(DOUT, CLK);                               
                                                            
#define I2C_ADDRESS 0x3C                                    //Defines the i2c adress of the 32x128 oled
SSD1306AsciiAvrI2c oled;                                    
//-----------------------------------------------------------
const int led = 9;                                          //led to arduino pin 9
const int buzzer = 5;                                       //buzzer to arduino pin 5
const int buttonPlus = 6;                                   //plus button to arduino pin 6
const int buttonMinus = 7;                                  //minus button to arduino pin 7
const int buttonTare = 8;                                   //tare button to arduino pin 8

int buttonStatePlus = 0;                                    //variable for reading the plus button status
int buttonStateMinus = 0;                                   //variable for reading the minus button status
int buttonStateTare = 0;                                    //variable for reading the tare button status

int threshold = 2 ;                                         //tourqe threshold level (this is set via plus and minus buttons, actual tourqe wanted)
int threshold1 = 1 ;                                        //warnig before tourqe threshold level (this is also set via plus and minus button, beeps one newtonmetre before actual wanted tourqe level)
//-----------------------------------------------------------
void setup() {                                              //start of the setup

  oled.begin(&Adafruit128x32, I2C_ADDRESS);                 //starts oled
  oled.setFont(Arial14);                                    //sets oled font
  oled.set2X();                                             //zooms the font by a factor of two so that the complete screen is filled
  
  pinMode(led, OUTPUT);                                     //sets the ledpin as an output
  pinMode(buzzer, OUTPUT);                                  //sets the buzzerpin as an output
  pinMode(buttonPlus, INPUT_PULLUP);                        //sets the plus button pin as a pulled up input
  pinMode(buttonMinus, INPUT_PULLUP);                       //sets the minus button pin as a pulled up input
  pinMode(buttonTare, INPUT_PULLUP);                        //sets the tare button pin as a pulled up input
 
  tone(buzzer, 1500);                                       //sounds buzzer at 1500HZ until later notone is called
  oled.print("Tare");                                       //displays "Tare" on oled
  
  scale.set_scale(-11450);                                  //this value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(10);                                           //tares the scale with 10 samples (less samples = faster, less acurate and more samples = slower, more acurate) 
  
  noTone(buzzer);                                           //notone shuts down the buzzer

  oled.clear();                                             //completly clears the oled
   
  }                                                         //end of the setup
//-----------------------------------------------------------
void loop() {                                               //start of the loop
  //main code start, the faster the better
  float tourqe = abs(scale.get_units());                    //converts value from HX711 to the float data type, makes negative values positive with abs and stores it       
  
  oled.print(tourqe);                                       //displays stored float value from HX711 on oled                                         
  oled.print(" Nm                        ---");             //displays "Nm" after tourqe value
  oled.println();                                           //starts a new line on the oled
//--------------------------------------------------------- 
  if (tourqe < threshold && tourqe > threshold1) {          //if tourqe value is between threshold and threshold1
     tone(buzzer, 2000, 100);                               //beeps buzzer at 2000HZ for 100 milliseconds to let you know you are close
     }                                                      //ends if statement
  
  if (tourqe > threshold) {                                 //if tourqe value is over set threshold 
     tone(buzzer, 2000, 200);                               //constanstly sounds buzzer at 2000HZ for 200 milliseconds
     digitalWrite(led, HIGH);                               //turns the led on
     }                                                      //ends if statement
  else {digitalWrite(led, LOW);                             //else it turns off the led
     }  
  //main code end                          
//-----------------------------------------------------------
  //this code is only needed when button is pressed
  if (digitalRead(buttonPlus) == LOW) {                     //if plus button is pressed  
     digitalWrite(led, HIGH);                               //turns the led on
     tone(buzzer, 1500, 25);                                //sounds the buzzer at 1500HZ for 25 milliseconds
     threshold += 1;                                        //adds 1 to the threshold
     threshold1 += 1;                                       //adds 1 to the threshold1
     digitalWrite(led, LOW);                                //turns the led off
     oled.print(threshold);                                 //displays the now set threshold on the oled
     oled.print(" Nm SET                        ---");      //displays "Nm SET" after the threshold
     }                                                      //ends if statement

  if (digitalRead(buttonMinus) == LOW) {                    //if minus button is pressed
     digitalWrite(led, HIGH);                               //turns the led on
     tone(buzzer, 1500, 25);                                //sounds the buzzer at 1500HZ for 25 milliseconds
     threshold -=1;                                         //subtracts 1 from the threshold
     threshold1 -=1;                                        //subtracts 1 from the threshold1
     digitalWrite(led, LOW);                                //turns the led off
     oled.print(threshold);                                 //displays the now set threshold on the oled
     oled.print(" Nm SET                        ---");      //displays "Nm SET" after the threshold
     }                                                      //ends if statement

  if (digitalRead(buttonTare) == LOW) {                     //if tare button is pressed
     oled.clear();                                          //completly clears the oled
     tone(buzzer, 1500);                                    //sounds the buzzer constantly at 1500HZ
     digitalWrite(led, HIGH);                               //turns the led on
     oled.print("TARE");                                    //displays "TARE"
     scale.tare(10);                                        //tares the scale with 10 samples (less samples = faster, less acurate and more samples = slower, more acurate) 
     noTone(buzzer);                                        //notone shuts down the buzzer
     digitalWrite(led, LOW);                                //turns the led off
     oled.clear();                                          //completly clears the oled
     }                                                      //ends if statement
  //end of butten press code
}                                                           //end of the loop

The code basically gets the value from an hx711 board and displays it on an oled and there are 3 buttons one led and a buzzer, a tare button, a plus and minus button wich are setting a threshold at wich the buzzer sounds and a threshold1 at wich the buzzer beeps.

thanks for any advice.

Dunno..

Does the buzzer routine hold up the program, for the duration of the "buzz" ? if so that might save a lot of time if you can think of another method, I guess your program spends most of its time "buzzing" if thats the case.

( not come across "tone" before , why not use a buzzer that just operates when its powered, then you could use "millis" ( see blink without delay) so as not to wait whilst it sounds)

You need to do some measurements to identify what parts of the code are slow. Record the value of micros() before and after different parts of the program and look at the results.

...R

hammy:
Dunno..

Does the buzzer routine hold up the program, for the duration of the "buzz" ? if so that might save a lot of time if you can think of another method, I guess your program spends most of its time "buzzing" if thats the case.

( not come across "tone" before , why not use a buzzer that just operates when its powered, then you could use "millis" ( see blink without delay) so as not to wait whilst it sounds)

I tested it and the tone function doesn't seem to delay the sketch, but I'm going to look into the tone delay tomorrow again,

Thanks

You are using a blocking HX711 library.

Selectable 10SPS or 80SPS output data rate

which SPS did you select?

You need to output over 1KiB of data to refresh each frame (at least with buffered SSD1306 libraries), in most cases I2C is the limiting factor. Try increasing the I2C clock frequency to 400 kHz instead of 100 kHz.

Pieter

PieterP:
You need to output over 1KiB of data to refresh each frame (at least with buffered SSD1306 libraries), in most cases I2C is the limiting factor. Try increasing the I2C clock frequency to 400 kHz instead of 100 kHz.

Pieter

SSD1306Ascii is an unbuffered character only library for small OLED displays like the Adafruit 1.3" and 0.96" Monochrome displays.

So thank you all for the help, i tried several things, but the thing that slowed the code down the most was the abs() function

float tourqe = abs(scale.get_units());

at the start of the main loop, i simply removed it, because it was just a cosmetic thing to not display a negative number

The abs function isn't slow, you used it incorrectly, and the actual slow function is scale.get_units.

From the abs documentation:

Because of the way the abs() function is implemented, avoid using other functions inside the brackets, it may lead to incorrect results.

If you read the actual source code, you'll see that by using abs like that, you're calling get_units twice. This will slow down your code significantly if that function is expensive. It will also not be correct all of the time if the sign changes between successive readings.

#define abs(x) ((x)>0?(x):-(x))

That being said, it would probably make more sense to change it to an inline, constexpr template function:

#undef abs
template <class T> inline constexpr T abs(T value) {
  return value > 0 ? value : -value;
}

PieterP:
The abs function isn't slow, you used it incorrectly, and the actual slow function is scale.get_units.

From the abs documentation:
If you read the actual source code, you'll see that by using abs like that, you're calling get_units twice. This will slow down your code significantly if that function is expensive. It will also not be correct all of the time if the sign changes between successive readings.

#define abs(x) ((x)>0?(x):-(x))

That being said, it would probably make more sense to change it to an inline, constexpr template function:

#undef abs

template inline constexpr T abs(T value) {
 return value > 0 ? value : -value;
}

:o

In the standards, abs is not (and should not be) defined as a macro. abs is already provided by stdlib.h as a non-macro, and Arduino is redefining it in a non-standard way!

There's already a couple open issues for this defect:

So here is the next update of the topic,

instesd of the abs() function Im now using the fabs() function, slows the scetch not noticeably down and works great for my purposes.

Thanks.