Code Optimieren von jemanden der davon mehr versteht als ich :)

Hi zusammen!
das ist mein erster Beitrag in diesem Forum und ich glaube auch jemals in einem Forum... crazy.

Ich habe kein wirkliches Problem aber ich glaube es wär ganz cool wenn sich jemand meinen Code anschaut und vielleicht ein paar tipps hat was ich optimieren kann :slight_smile:

Was macht mein Code?

Ich habe einen Distanzmesser gebaut, der die gemessene Distanz in Meter umwandelt und an einem Display anzeigt sowie per NRF24 an einen Empfänger sendet. Über einen Voltage Divider kann der Arduino den Ladezustand des internen Lipo Akkus erkennen oder Ob eine Externe Stromquelle angeschlossen ist.

Simple. Dachte ich zumindest vor 1,5 Jahren als ich keine Ahnung von Code oder einem Arduino hatte.

Ich hab mich also Stück für Stück ran gearbeitet, dabei aber bestimmt ein paar Grundlagen verpasst ...

Seid mir deshalb nicht böse wenn der Code etwas umständlich o.ä. ist, ich habe mir viele teile kopiert und zusammengeklebt, und irgendwie hab ich es mit meinem Halbwissen hinbekommen, aber bestimmt nicht so super effizient :slight_smile:

Konkrete Hardware:

Ich habe einen Arduino Nano RF an dem sind:
-Vier Knöpfe (D4,5,6,7)

  • ein 9mw Laser (D13)
  • Ein Benewake TF02 Pro LIDAR (D2,3)
  • Ein SSD1306 0.96OLED Display (A4,5)
    -Ein Lipo mit Charger
    -Boost Modul für den Lipo
    -Ein Step down Konverter für 14V eingang

Anbei Hab ich auch noch einen Schaltplan falls das Hilft
Schaltplan

(in einer Späteren version sollen die Distanzdaten noch per RS232 über Kabel an einen anderen, Seriellen Empfänger geschickt werden, aber das ist noch nicht im Code)

Ich freu mich über jede hilfe! :blush:

Grüße, Consti!

hier also der Code:


// *** v0.6.8 ***
// by constantin iandolino



#include<SoftwareSerial.h>
SoftwareSerial Serial1(3, 2);

#include <RF24.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include <nRF24L01.h>
#define OLED_RESET     -1
#define voltagePin A3
#include <Wire.h>
#include <Metro.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

#define OLED_ADDR   0x3C

Metro DELAY10K = Metro(10000);
Metro DELAY10  = Metro(10);

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

float dist;
int strength;
int check;
int i;
int uart[9];
const int HEADER = 0x59;
RF24 radio(9, 10);
const byte address[6] = "00001";

int val;
float press;
int count;
int buttonplus = 6;
int buttonminus = 7;
int buttonlaser = 4;
int Laser = 13;

const float mvpc = 5.1 ;
int counts = 3.7;
int countssaved = 0;
float mv = 0;
//float multiplier = 3.1;
//float output = 0;
//int charge = 0;



void setup()                                 
{


  Serial.begin(9600);
  Serial1.begin(115200);
  Serial.print("starting...");

  radio.begin();


  radio.openWritingPipe(address);             // RADIO
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate( RF24_250KBPS );
  radio.stopListening();

  pinMode(buttonplus, INPUT_PULLUP);          // BUTTONS
  pinMode(buttonminus, INPUT_PULLUP);
  pinMode(buttonlaser, INPUT_PULLUP);
  pinMode(Laser, OUTPUT);
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay();
  display.setRotation(2);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(7, 20);
  display.println("CINEMETER");

  display.setCursor(7, 35);
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.println("starting...");
  display.display();
  delay(500);
}



void loop()
{
  if (Serial1.available())                    // LIDAR 
  {
    if (Serial1.read() == HEADER)
    {
      uart[0] = HEADER;
      if (Serial1.read() == HEADER)
      {
        uart[1] = HEADER;
        for (i = 2; i < 9; i++)
        {
          uart[i] = Serial1.read();
        }
        check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
        if (uart[8] == (check & 0xff))
        {
          dist = uart[2] + uart[3] * 256;
          strength = uart[4] + uart[5] * 256;

          float Distanceoffset =  ((dist / 100) + (press / 100));    // DISTANZ IN METER (+ Offset durch Button )
                                                                       


          int SIGNAL = (strength / 100);                          // SIGNALSTÄRKE

          val = digitalRead(buttonplus);                          // BUTTONS OFFSET
          if (val == HIGH) {
            press = count++;
            delay(10);
          }
          val = digitalRead(buttonminus);
          if (val == HIGH) {
            press = count--;
            delay(10);
          }

          val = digitalRead(buttonlaser);                         // BUTTON ZUM TRIGGERN DES LASER
          if (val == LOW) {
            digitalWrite(Laser, HIGH);

          }

          //Serial.print(press/100);


          display.clearDisplay();
          display.setRotation(2);
          display.setTextSize(1);
          display.setTextColor(WHITE);

          display.setCursor(0, 0);    // DISTANZ OFFSET
          display.println("OFST:");
          display.setCursor(40, 0);
          display.print(press, 0);
          display.print("cm");
          display.setCursor(0, 10); // SIGNAL
          display.setTextSize(1);
          display.print("SGNL:");
          display.setCursor(40, 10);
          display.print(SIGNAL);
          display.setCursor(0, 20); // BATTERY
          display.setTextSize(1);
          display.print("BATT:");

          int charge = map(counts, 175, 266, 0, 100);             // VOLTAGE DIVIDER MAPPEN AUF PROZENTE
          int charge2 = map(countssaved, 175, 266, 0, 100);

          mv = counts * mvpc;                                    // VOLTAGE
          //output = (mv * multiplier)/1000 ;


          if (DELAY10K.check() == 1) {                          //VOLTAGE AUSLESEN
            counts = analogRead(voltagePin);
            Serial.println(counts);
            countssaved = counts;                               // HIER MUSSTE ICH DIE VOLTAGE IRGENDIWE ZWISCHENSPEICHER BIS -
                                                                // ZUM NÄCHSTEN READOUT
          }

          if (countssaved > 1 && countssaved  < 185)              //DISPLAY MIT VERSCHIEDENEN "POWER" DISPLAYS
          { display.setTextColor(WHITE);
            display.setCursor(40, 20);
            display.print("LOW");

          }


          if (countssaved > 185)
          { display.setTextColor(WHITE);
            display.setCursor(40, 20);
            display.print(charge2);
            display.print("%");
          }


          if (countssaved == 0)
          { display.setTextColor(WHITE);
            display.setCursor(40, 20);
            display.print("DC PWR");
          }

          display.setTextSize(3);   // DISTANCE
          display.setTextColor(WHITE);
          display.setCursor(0, 35);
          display.print(Distanceoffset);


          display.setCursor(90, 0);
          display.setTextSize(1);
          display.println("v0.66");
          display.setCursor(90, 13);
          display.setTextSize(1);
          display.println("METER");

          //display.setFont();
          display.setCursor(90, 30);
          display.setTextSize(4);
          display.println("m");

          display.display();


          radio.write(&Distanceoffset, sizeof(Distanceoffset));      // SENDEN AN EMPFÄNGER

          Serial.println(Distanceoffset, 2);
        }
      }
    }
  }
}

Alles was sich nicht verändern lässt: const machen. (Pins können sich z.B. nicht ändern)

Ein int benötigt bei Dir 2 byte. Ein byte reicht auch.
Zudem könnte ein int auch negativ sein. Wenn das nicht notwendig ist, unsigned int draus machen. (wenn das ene byte nicht reicht)

print und println mit dem F-Makro setzen.

Den find ich schön:

Mach das nicht.
Schreib Dir oben eine Konstante und verwende die im Code.

Wenn Du nur ein Zeichen ausgibst, brauchst Du "" nicht, das geht auch mit '%'.

Das countssaved könnte mann auch mit einem switch/case auflösen, damit nicht alle Bedingungen geprüft werden.
PS: Wenn countssaved 1 ist bekommst Du keine Ausgabe

Dann könntest die einzelnen Programmteile in Funktionen verpacken und nicht alles als Spaghetticode im loop hinterlegen.

Den Display nur schreiben, wenn sich ein Wert geändert hat.

Aber schick...
Wenns funktioniert ist das ja schon mal was :slight_smile:
Na denne.

1 Like

Wenn ein Zeichen zur Verfügung steht, lies neun.

Das wird interessante Ergebnisse liefern.

top danke dir!

alright, ja das könnte ich mir mal anschauen, aber keine ahnung wie ich das dann genau mach tbh.
ich werds bestimmt rausfinden! danke für die ansätze :slight_smile:

tatsächlich liefert es dann die Distanz und die Signalstärke, ich hab den code direkt aus der Anleitung :sweat_smile:

Dann kann man also dem Hersteller nicht vertrauen? Gut zu wissen.

bisschen sus. sind die eh..
wie würdest du es schreiben?

Ziemlich hüstel komische Frage.

Ich würde nur von der seriellen Schnittstelle lesen, wenn auch etwas da ist.

Ansonsten das Datenblatt studieren, um das genaue Nachrichtenformat zu ermitteln,
die Nachricht des Moduls ganz empfangen, und dann erst verarbeiten.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.