Arduino, strippen van decimale waarde

met return; kun je op een willekeurig punt uit een subroutine springen. Dat werkt ook voor de loop() funktie. De Arduino kernel begint dan weer bovenin de loop();

code:



void loop()
{
   ... 

   if( ... )
   {  ...
      return;
   } 

   ...
}

kan ook met een if-else

code:



void loop()
{
   ... // bereken waarde

   if(...)
   {  ... // fout - afhandleing 
   }
   else
   {  ... // Display update
   }
}
benleentje

Golden Member

Eigenlijk is mijn bedoeling de loop hier op te splitsen dus een
vork met twee tanden die naar beneden wijst.
Als de OR vergelijking waar is, wat te hoge temperaturen betreft, dan wil ik niet meer in de hoofdloop terecht willen komen.
Het aansturen van het display en de uiteindelijke "display.display();" wil ik in het error deel afhandelen.

De vork of splitsing die je bedoelt is dan gewoon met de IF vergelijking

c code:


if( (tAmp > T_Amp_Err) || (tPsu > T_AmT_PSU_Err p_Err) || (tTrafo> T_Trafo_Err ))
{
   //Handle error stuff in subroutine error_handler
   error_handler()
}

Dan verderop in de code buiten de loop() maak je bv zoiets

c code:


void error_handler() {
    {
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(x,y);
    display.println(text);
  if(d){
        display.display();
       }
    
    }

}

In het eerst deel van de code staat achter de IF regel dan nu een sprong naar error_handler maar dat mag ook elke andere naam hebben die je wilt als die maar overeenkomt met de naam van het subroutine.

Na het uitvoeren van error_handler spring de code automatisch terug naar de regel onder de vorige aanroep naar deze routine en je kan error_ahndlerdan nu ook vanaf meerdere plaatsen aanroepen.

display.setTextSize(1); is eigenlijk ook gewoon een aanroep van een routine. Die routine bevind zich hier in een bibliotheek en houd je loop() kort en bondig.

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.

Hallo,

Ik heb nu een paar keer naar het stukje code van 2 april zitten kijken en ik heb veel moeite om te ontcijferen wat er precies gebeurt. Besteed meer tijd aan de opmaak van je code. Je schema's zien er altijd tot in de puntjes perfect uit. Gebruik dezelfde mindset voor software. :) Zeker als je later nog eens wat met de code wilt doen is het erg fijn als het een beetje leesbaar is.

Een paar tips om je op weg te helpen:

Stijl
Leer jezelf een stijl aan. Welke stijl dit is maakt in principe niet zoveel uit maar kies er een en gebruik die consistent door heel je code. Zelf gebruik ik de volgende regels:

- Alles in het Engels en duidelijke namen. De bedoeling is dat de variabelen en functie namen zo duidelijk gekozen zijn dat er maar 1 ding mee bedoeld kan worden. Pas op met afkortingen, temp kan zijn temperature of temporarily.
- CamelCase toepassen. Dit wil zeggen dat ieder woord begint met een hoofdletter. danIsHetNogSteedsRedelijkLeesbaarOokAlHebJeGeenSpaties
- Deel je code op in meerdere kleine functies. Sommige pleiten dat een stukje code nooit groter mag zijn dan op je scherm past.
- Globale variabelen, probeer ze te voorkomen. Globale variabelen maken snel een grote brij van je code.
- Uitlijning van haakjes, zorg dat de inspringing klopt. TAB is hierbij je vriend!
- Variabelen: CamelCase, Eerste letter klein
- Functies: CamelCase, Eerste letter groot
- Defines: Alles HOOFDLETTERS
- Types / structs / enums: CamelCase, Eerste letter groot

Verder ben ik persoonlijk voorstander van de stdint. Zo weet je altijd hoe groot je variabelen zijn ongeacht je processor. Dat maakt je code ook portable tussen verschillende processoren. Een int is op een classic Arduino 16 bits maar op een ESP32 32 bits. uint32_t en int32_t zijn altijd 32 bits.

Een beginnetje, ik kan het hier niet testen, ik heb geen zin om alle spullen te installeren.
Maar zo krijg je wel een idee.

c code:


#include <JC_Button.h>                                                          // https://github.com/JChristensen/JC_Button
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ADC.h>
#include <ADC_util.h>


// pin assignments
#define BTN_IMPEDANCE_PIN            2            //Frontpanel 'input impedance' button
#define BTN_OUTPUT_ENABLE_PIN        3            //Frontpanel 'output enabled' button
#define REL_INPEDANCE_PIN            4            //Relais to switch between 50 Ohm or 1K input impedance
#define REL_OUTPUT_ENABLE_PIN        5            //Output Enable Relais
#define LT1210_ENABLE_PIN            6            //LT1210 Enable, used for "High Temp" condition
#define OLED_RESET_PIN               4            //Reset pin for oled display
#define ADC_AMP_TEMP_PIN             14        
#define ADC_PSU_TEMP_PIN             15        
#define ADC_TRAFO_TEMP_PIN           16        

// Defines
#define ADC_REF_VOLTAGE              3.288f       //Reference voltage used for ADC
#define UART_BAUD                    9600
#define ADC_AVERAGING                64
#define ADC_RESOLUTION               16
#define ADC_CONVERSION_SPEED         ADC_CONVERSION_SPEED::VERY_LOW_SPEED
#define ADC_SAMPLING_SPEED           ADC_SAMPLING_SPEED::MED_SPEED
#define I2C_OLED_ADDRESS             0x3C
#define TEMP_AMP_MEASURE_INTERVAL    1000        //miliseconds
#define TEMP_PSU_MEASURE_INTERVAL    1000        //miliseconds
#define TEMP_TRAFO_MEASURE_INTERVAL  1000        //miliseconds
#define UPDATE_DISPLAY_INTERVAL      1000        //miliseconds
#define TEMP_AMP_MAX                 70        
#define TEMP_PSU_MAX                 70        
#define TEMP_TRAFO_MAX               70        


// Global objects
ToggleButton btnInputImpedance(BTN_IMPEDANCE_PIN);
ToggleButton btnOutputEnable(BTN_OUTPUT_ENABLE_PIN);
Adafruit_SSD1306 display(OLED_RESET_PIN);
ADC adc;

// Global variables, BOOOOH, this is the way arduino does things so i'll do as well
uint64_t prevAmpTempMeasured = 0;
uint64_t prevPSUTempMeasured = 0;
uint64_t prevTrafoTempMeasured = 0;
uint64_t prevDisplayUpdated = 0;
float tempAmp = 0;
float tempPSU = 0;
float tempTrafo = 0;

void setup()   
{                
    Serial.begin(UART_BAUD);

    // ADC0 Settings Teensy-4, Teessy-LC
    adc.adc0->setAveraging(ADC_AVERAGING);                
    adc.adc0->setResolution(ADC_RESOLUTION);              
    adc.adc0->setConversionSpeed(ADC_CONVERSION_SPEED);   
    adc.adc0->setSamplingSpeed(ADC_SAMPLING_SPEED);       

    //by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
    display.begin(SSD1306_SWITCHCAPVCC, I2C_OLED_ADDRESS); 

    // Clear Display buffer.
    display.clearDisplay(); 

    // initialize the button objects
    btnInputImpedance.begin();
    btnOutputEnable.begin();

    // set the following pins as outputs
    pinMode(REL_INPEDANCE_PIN, OUTPUT);
    pinMode(REL_OUTPUT_ENABLE_PIN, OUTPUT);
    pinMode(LT1210_ENABLE_PIN, OUTPUT);
    
    //show the initial states
    digitalWrite(REL_INPEDANCE_PIN, btnInputImpedance.toggleState());
    digitalWrite(REL_OUTPUT_ENABLE_PIN, btnOutputEnable.toggleState());
}




void loop() 
{
    //if button state changed, switch the relais
    if (btnInputImpedance.changed()){
        digitalWrite(REL_INPEDANCE_PIN, btnInputImpedance.toggleState());
    }
    
    if (btnOutputEnable.changed()){
        digitalWrite(REL_OUTPUT_ENABLE_PIN, btnOutputEnable.toggleState());
    }


    //Read about overflow!!!
    //https://www.norwegiancreations.com/2018/10/arduino-tutorial-avoiding-the-overflow-issue-when-using-millis-and-micros/
    if(millis() - prevAmpTempMeasured > TEMP_AMP_MEASURE_INTERVAL)
    {
        prevAmpTempMeasured = millis();
        tempAmp = GetTempAmplifier();
    }
    
    if(millis() - prevPSUTempMeasured > TEMP_PSU_MEASURE_INTERVAL)
    {
        prevPSUTempMeasured = millis();
        tempPSU = GetTempPowerSupply();
    }
    
    if(millis() - prevTrafoTempMeasured > TEMP_Trafo_MEASURE_INTERVAL)
    {
        prevTrafoTempMeasured = millis();
        tempTrafo = GetTempTransformer();
    }
    
    if(millis() - prevDisplayUpdated > UPDATE_DISPLAY_INTERVAL)
    {
        prevDisplayUpdated = millis();
        display.clearDisplay();
        
        if(tempAmp < TEMP_AMP_MAX){
            PrintTemperature("Ta", tempAmp, 1, 25, 1, WHITE);
        } else {
            PrintTemperature("Ta", tempAmp, 1, 25, 1, RED);
        }
        
        if(tempPSU < TEMP_PSU_MAX){
            PrintTemperature("Ta", tempPSU, 1, 25, 1, WHITE);
        } else {
            PrintTemperature("Ta", tempPSU, 1, 25, 1, RED);
        }
        
        if(tempTrafo < TEMP_TRAFO_MAX){
            PrintTemperature("Ta", tempTrafo, 1, 25, 1, WHITE);
        } else {
            PrintTemperature("Ta", tempTrafo, 1, 25, 1, RED);
        }
        
        if(outputEnabled){
            PrintText("OUTPUT           ON", 0, 1, 0);  
        } else
        
        if (outputEnabled) {
            PrintText("OUTPUT           ON", 0, 1, 0);  
        } else {
            PrintText("OUTPUT           OFF", 0, 1, 0);
        }

        if (lowImpedanceEnabled) {
            PrintText("INPUT Impedance  1K", 0, 12, 1);  
        } else {
            PrintText("INPUT Impedance  50", 0, 12, 1);
        }
        
        display.display();
    }
}



float GetTempAmplifier()
{
    uint16_t rawValue = adc->adc0->analogRead(ADC_AMP_TEMP_PIN);
    float result = rawValue * ADC_REF_VOLTAGE * 0.02 / adc->adc0->getMaxValue();
    return result;
}

float GetTempPowerSupply()
{
    uint16_t rawValue = adc->adc0->analogRead(ADC_PSU_TEMP_PIN);
    float result = rawValue * ADC_REF_VOLTAGE * 0.02 / adc->adc0->getMaxValue();
    return result;
}

float GetTempTransformer()
{
    uint16_t rawValue = adc->adc0->analogRead(ADC_TRAFO_TEMP_PIN_TEMP_PIN);
    float result = rawValue * ADC_REF_VOLTAGE * 0.02 / adc->adc0->getMaxValue();
    return result;
}

void PrintTemperature(String prefix, float temp, uint16_t xPos, uint16_t yPos, uint16_t size, Color color)
{              
    display.setTextSize(size);
    display.setTextColor(color);
    display.setCursor(xPos,yPos);
    display.print(prefix);
    display.println(String(temp));
}

void PrintText(String text, int x, int y,int size) 
{
    display.setTextSize(size);
    display.setTextColor(WHITE);
    display.setCursor(x,y);
    display.println(text);
}
PE2BAS
blackdog

Golden Member

Hi hardbass, :-)

Dank je voor je input!
Ik ga dat opnemen/opslaan zodat ik er op mijn Servers naar terug kan grijpen.
Een aantal keren, maar dat is al wat langer geleden, heb ik al eens gekeken hoe het een en ander duidelijker kan doen.

Maar je moet niet vergeten hoe ik worstel met "taal" samen met gebrek aan kennis van basis zaken, ik zal me eerst een moeten gaan bezig houden met Arduino code 101 *grin*

Ook wordt ik nogal eens om mijn oren geslagen waar deKees mij al voor waarschuwde, let op met kopiëren van code!
Mijn code voor de temperatuur error melding werkte goed voor de sensor die op de hoek van mijn breadbordje zat, ik kon daar goed bij.
Daar ik de code had gekopieerd voor de andere twee sensoren was ik vergeten het sensor nummer aan te passen, de muts die ik ben.

Ik was toen jij je laatste post deed ook net bezig de code wat netter te maken en de code te verwijderen die niet meer nodig is.
Soms is het voor mij handiger om zaken in het Nederlands te doen, dat doe ik dan, maar dan staat er dus Nederlandse en Engelse tekst door elkaar.
Dat is dan jammer genoeg noodzakelijk als ik ergens niet uit kom, later maak ik er dan weer één taal van.

Van een aantal variabelen die ik heb afgekort was het de bedoeling de omschrijving hiervan boven in de code aan te geven als tekst om het duidelijker te maken.

Zover was ik net gekomen met het opschonen van de code tijdens jouw post:

c code:


#include <JC_Button.h>                                                          // https://github.com/JChristensen/JC_Button
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4


//unsigned long Old_beep1 = 0;
//unsigned long Old_beep2 = 0;
//const int Interv_beep1 = 400;
//const int Interv_beep2 = 800;
unsigned long currentMillis_1;
unsigned long currentMillis_2;


// ADC Setup
#include <ADC.h>
#include <ADC_util.h>
ADC* adc = new ADC();

//Gebruikt referentie spanning voor de ADC van de Teensy-4
float Ref = 3.288;

// Variabelen voor de TMP37 sensoren 
float T_Amp_Cor = 0;
float T_PSU_Cor = 0;
float T_Trafo_Cor = 0;

// Error temperatuur per sensor, geeft de maximale temperatuur aan die bereikt mag worden per meetpunt in graden Celcius voor de foutmelding
byte T_Amp_Err = 27;
byte T_PSU_Err = 27;
byte T_Trafo_Err = 27;


// Variabelen nodig voor de temperatuur omzetting
float T_Amp = 0,  T_PSU = 0,  T_Trafo = 0;
int T_Amp_D = 0, T_PSU_D = 0, T_Trafo_D = 0;

// Variabelen voor timing berekening van de temperatuur, ongeveer 1 x per seconde
const unsigned long E_I_Ta = 1000;
unsigned long P_T_Ta = 0;

const unsigned long E_I_Tp = 1020;
unsigned long P_T_Tp = 0;

const unsigned long E_I_Tt = 1040;
unsigned long P_T_Tt = 0;

// Setup Display
Adafruit_SSD1306 display(OLED_RESET);

// pin assignments
const byte
    Output_1(4),                                                             // Ingang relais, schakeld de ingang om in 50 Ohm of 1K Impedantie, toggle funcie d.m.v. drukknop op het front
    Output_2(5),                                                             // Uitgang relais, schakeld de uitgang in of uit, toggle funcie d.m.v. drukknop op het front
    Output_3(6),                                                             // LT1210 Enable, Wordt gebruikt om de LT1210 uit te schakelen bij te hoge temperaturen
    BUTTON1_PIN(2),                                                          // Drukknop voor het ingang relais, de interne Pull Up van de ingang wordt gebruikt
    BUTTON2_PIN(3);                                                          // Drukknop voor de uitgang om in of uit te schakelen, toggle funcie d.m.v. drukknop op het front, de interne Pull Up van de ingang wordt gebruikt


    ToggleButton                                                             // Defineer de drukknop library voor de drukknop functies
    btn1(BUTTON1_PIN, false, 5),                                             // Drukknop-1 voor de ingang impedantie, beginstand is uit en de debounce tijd is 5mS
    btn2(BUTTON2_PIN, false, 5);                                             // Drukknop-2 schakeld de uitgang aan of uit, beginstand is uit en de debounce tijd is 5mS

// variabele voor Drukknop status
byte state_btn1;
byte state_btn2;




void setup()   {                
Serial.begin(9600);

// ADC0 instellingen voor de Teensy-4, Teessy-LC
    adc->adc0->setAveraging(64);                                             // Hier wordt 64x middeling gebruikt
    adc->adc0->setResolution(16);                                            // Hier wordt de resolutie ingesteld op 16-Bits
    adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_LOW_SPEED);     // Hier wordt de conversie snelheid ingesteld
    adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED);              // Hier wort de Sample snelheid ingesteld


// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);                               // initialiseren van het Display met 12c adres van 0x3C

// Hieronder de code voor het weergeven van het logo, versienummer en weergave en beeper test
  display.clearDisplay(); 

  display.drawRect(1, 1, 126,31, WHITE);
  display.setTextSize(2);                                                    // 
  display.setTextColor(WHITE);                                               // 
  display.setCursor(18,9);                                                   // 
  display.println("NoiseAmp");                                               //
  display.display();
  delay(1000);

  display.clearDisplay(); 
  display.drawRect(1, 1, 126,31, WHITE);
  display.setTextSize(2);                                                    // 
  display.setTextColor(WHITE);                                               // 
  display.setCursor(11,9);                                                   // 
  display.println("Amsterdam");                                              //
  display.display();
  delay(1000);

    tone(8, 2000, 500);                                                      // Beeper test op Pin-8, 2KHz voor 500mSec

  display.clearDisplay(); 
  display.setTextSize(2);                                                    // 
  display.setTextColor(WHITE);                                               //
  display.setCursor(0,0);                                                    // 
  display.println("Gen-Amp-01");
  
  display.setTextSize(1);
  display.setCursor(0,22);
  display.println("V1.0  C");                                                // Software versie welke gebruikt wordt
  display.drawCircle(38, 25, 5, WHITE);
//  display.setCursor(20,30);
    
  display.display();
  delay(2000);

// initialiseren van de button objects
    btn1.begin();
    btn2.begin();

// Stel de volgende pinnummers in als uitgang
    pinMode(Output_1, OUTPUT);
    pinMode(Output_2, OUTPUT);
    pinMode(Output_3, OUTPUT);
    
// Steld de standaard waarde van de Button uitgangen in
    digitalWrite(Output_1, btn1.toggleState());
    digitalWrite(Output_2, btn2.toggleState());
}





void loop() {

// LT1210 temperatuur berekening 
    unsigned long C_T_Ta = millis();
    if ( C_T_Ta - P_T_Ta >= E_I_Ta ) {
    T_Amp = adc->adc0->analogRead(14);
    T_Amp_D = (T_Amp*Ref/adc->adc0->getMaxValue()/0.02) +(T_Amp_Cor);
    P_T_Ta = C_T_Ta;
    }
    
// Voedings temperatuur berekening
    unsigned long C_T_Tp = millis();
    if ( C_T_Tp - P_T_Tp >= E_I_Tp ) {
    T_PSU = adc->adc0->analogRead(15);
    T_PSU_D = (T_PSU*Ref/adc->adc0->getMaxValue()/0.02) +(T_PSU_Cor);
    P_T_Tp = C_T_Tp;
    }

// Trafo temperatuur berekening
   unsigned long C_T_Tt = millis();
    if ( C_T_Tt - P_T_Tt >= E_I_Tt ) {
    T_Trafo = adc->adc0->analogRead(16);
    T_Trafo_D = (T_Trafo*Ref/adc->adc0->getMaxValue()/0.01) +(T_PSU_Cor);  
    P_T_Tt = C_T_Tt;
    }

//  Code voor het testen van te hoge temperaturen
//  Te hoge temperatuur vergelijking, gemeten temperatuur t.o.v. ingestelde limit per meetpunt

if( (T_Amp_D >= T_Amp_Err) || (T_PSU_D >= T_PSU_Err) || (T_Trafo_D >= T_Trafo_Err))
    {

// Zet de relais in de gewenste stand tijdens te hoge temperaturen

  digitalWrite(Output_1, 0);                                                  // Zet het relais in de gewenste stand tijdens de temperatuur error
  digitalWrite(Output_2, 0);                                                  // Zet het relais in de gewenste stand tijdens de temperatuur error
  digitalWrite(Output_3, 0);                                                  // Schakeld de LT1210 op Disable

  state_btn1 = 0;
  state_btn2 = 0;

// Error beeper tijdens te hoge temperaturen
    currentMillis_1 = millis();                                               // Bepaald de repetitie tijd onderstaande beeper
    if ( currentMillis_1 - Old_beep1 >= Interv_beep1) {
    Old_beep1 = currentMillis_1;
    
    tone(8, 1000, 100);                                                      // Beeper op pin-8 geeeft toon van 1000Hz voor 100mSec
    }

  display.clearDisplay();                                                    // Maakt het scherm schoon

// Schrijf de temperaturen naar het scherm
  String T_Amp_Display =  String(T_Amp_D);                 
  robojaxText(T_Amp_Display, 17, 25, 1, false);                              // Plaatst de temperatuur variabele van de LT1210 op het display
  robojaxText("Ta", 1, 25, 1, false);
  robojaxText("C", 29, 25, 1, false);
  display.drawRect(35, 25, 2, 2, WHITE);
  
  String T_PSU_Display =  String(T_PSU_D);                 
  robojaxText(T_PSU_Display, 62, 25, 1, false);                              // Plaatst de temperatuur variabele van de voeding op het display
  robojaxText("Tp", 46, 25, 1, false);
  robojaxText("C", 74, 25, 1, false);
  display.drawRect(80, 25, 2, 2, WHITE);
  
  String T_Trafo_Display =  String(T_Trafo_D);                 
  robojaxText(T_Trafo_Display, 108, 25, 1, false);                           // Plaatst de temperatuur variabele van de trafo op het display
  robojaxText("Tt", 92, 25, 1, false);
  robojaxText("C", 120, 25, 1, false);
  display.drawRect(126, 25, 2, 2, WHITE);
  
// Schrijft in groot formaat "Temp ERROR" op het scherm als een van de drie temperaturen te hoog is
  display.drawRect(0, 0, 128,21, WHITE);                                     // Plaatst kader op het scherm
  display.setTextSize(2);                                                    // Dubbele tekst grote
  display.setTextColor(SSD1306_WHITE);                                       // 
  display.setCursor(5,3);                                                    // Begin positie onderstaande tekst
  display.println(F("Temp ERROR"));                                          // Plaat "Temp ERROR" op het display

  display.display();

 return;                                                                     // Keer terug naar de bovenzijde van de "void loop"
    }
    
// **************************** Einde hoge temperatuur foutcode **************************





// Deze code draait als de temperaturen in het kastje niet te hoog zijn.

// Als de  status van de Button uitgangen is veranderd, pas dan de uitgang aan.
    if (btn1.changed()) digitalWrite(Output_1, btn1.toggleState());
    if (btn2.changed()) digitalWrite(Output_2, btn2.toggleState());   

// Lees de drukknoppen uit
    btn1.read();
    btn2.read();

//  Bepaal de status van de knop uitgangen
    state_btn1 = digitalRead(4);
    state_btn2 = digitalRead(5);


// Plaats variabelen en vaste tekst voor de temperatuur metingen op het display en maakt eerst het display leeg
  display.clearDisplay();

  String T_Amp_Display =  String(T_Amp_D);                 
  robojaxText(T_Amp_Display, 17, 25, 1, false);                              // Plaatst de temperatuur variabele van de LT1210 op het display
  robojaxText("Ta", 1, 25, 1, false);
  robojaxText("C", 29, 25, 1, false);
  display.drawRect(35, 25, 2, 2, WHITE);
  
  String T_PSU_Display =  String(T_PSU_D);                 
  robojaxText(T_PSU_Display, 62, 25, 1, false);;                             // Plaatst de temperatuur variabele van de voeding op het display
  robojaxText("Tp", 46, 25, 1, false);
  robojaxText("C", 74, 25, 1, false);
  display.drawRect(80, 25, 2, 2, WHITE);
  
  String T_Trafo_Display =  String(T_Trafo_D);                 
  robojaxText(T_Trafo_Display, 108, 25, 1, false);;                          // Plaatst de temperatuur variabele van de trafo op het display
  robojaxText("Tt", 92, 25, 1, false);
  robojaxText("C", 120, 25, 1, false);
  display.drawRect(126, 25, 2, 2, WHITE);


// Plaatsen van de in en uitgang relais status op het scherm
  if (state_btn1  == 1 ) {
  robojaxText("OUTPUT            ON", 0, 1, 0, false);  
  } else {
  robojaxText("OUTPUT            OFF", 0, 1, 0, false);
  }

  if (state_btn2  == 1 ) {
  robojaxText("INPUT Impedance   1K", 0, 12, 1, false);  
  } else {
  robojaxText("INPUT Impedance   50", 0, 12, 1, false);
  }
 
  display.display();

}
void robojaxText(String text, int x, int y,int size, boolean d) 
    {
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(x,y);
    display.println(text);
  if(d){
        display.display();
       }
    }

Wat ik er bij heb gezet t.o.v. de vorige code die ik had laten zien is dit:
Logo en versie nummer van de code en een beeper test.
Aan gepaste tekst op de bovenste twee regels tijdens de temperatuur fout situatie.
Beeper die geluid blijft geven tijdens de fout situatie.

Wat ik er nog bij wil hebben:
Error afhandeling wat betreft de voeding, dat is stroomverbruik en/of spanning verschil tussen de + en de - 17,5V

Ik ben mij bewust dat dit allemaal erg lux is voor dit vesterker trapje, maar het is ook een leerproject.
Oja, ik verwacht niet dat mijn code de zelfde kwaliteit zal krijgen als mijn schema's, daar heb ik te veel aberraties voor. *grin*

Verder ben ik natuurlijk blij met jullie support!

Mijn familie bezoek in Brazil is nu bijna ten einde, en het uitgebreid spelen en testen is dus over, jammer genoeg.
Maar ik zal denk ik nog wel wat tijd over hebben, ten tijde van het herstel van mijn jetlag de komende dagen.

Dit is het breadboard waarop de code is getest.
Rechtsonder de drie temperatuur sensoren en net onder het oranje draadje onderaan de twee drukknopjes.

.
En dit zal ik nu moeten gaan missen... klik voor een mooi plaatje!

Groet en dank,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.

Op 20 april 2022 20:04:28 schreef hardbass:
- Deel je code op in meerdere kleine functies. Sommige pleiten dat een stukje code nooit groter mag zijn dan op je scherm past.

Ik vind dat een prima streven. Maar er zijn uitzonderingen. Beginnende programmeurs vinden dan dat DIT natuurlijk de uitzondering moet zijn. Dat is niet het geval. Gewoon opsplitsen.

De uitzondering vind ik bijvoorbeeld een functie waar een aantal gevallen afgehandeld/uitgesplitst moeten worden. Als na het uitsplitsen de acties "simpel" zijn dan kan je ze inline doen. Maar als je gaat smokkelen, twee regels kan ook inline, drie ook wel... enz. dan loopt het uit de hand.

De "voorbeeldprogrammas" waar ik mee begin die doen vaak "wat simpele initializaties" aan het begin van main:

https://github.com/raspberrypi/pico-examples/blob/master/adc/adc_conso…

Als je dan van meer dan 1 zo'n voorbeeldprogramma dingen combineert wordt het te groot. Dus hier deze initializatie... dat kan nog net. Maar als er iets bij komt dan zou ik init_gpio(); en print_header(); van maken: 2 regels. Het stuk d'r onder vind ik ook te lang:

code:


case 'c': handle_c (); break;
case 's': handle_s (); break;
...

Ik houd zelf niet van CamelCase (behalve in de naam van m'n bedrijf :-) ) De auteur van het gelinkte pico-project ook niet. Ik las "printhelp" als "prin the lp" en moest een 2e keer kijken. print_help was dan beter geweest. Of als je wel van CamelCase houdt: printHelp .

@bram: Je indentering klopt nog niet

code:


if  (...) {
   Deze code moet inspringen.
}

Aantal spaties mag je zelf een beslissing over nemen. Ik doe tegenwoordig meestal 2 of 3 (ik weet het niet, als ik het anders zou doen dan zou ik denken: er /is/ iets, maar ik weet niet wat... Verder automatische piloot.... :-) )

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
benleentje

Golden Member

ik zal me eerst een moeten gaan bezig houden met Arduino code 101 *grin*

Moeten moet van mij niet zo ;).

Ik kan je wel deze cursus aanbevelen het heet mij heel erg vooruit geholpen

https://www.udemy.com/course/beginning-c-plus-plus-programming/

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.

Uiteraard snap ik dat je als beginner ergens moet beginnen. Als ik terug kijk in de code die ik ooit maakte, brrr. Maar dat is ook niet erg, zeker zolang het hobby is. Wat betreft stijl, tja ieder zijn voorkeur. Mijn voorkeur komt uit C# visual studio. Deze doet heel erg veel opmaak voor je, sterker nog. Je kan met een druk op de knop automatisch alle opmaak netjes laten zetten. En ja dat werkt echt perfect. Daarbij komt dat de ArduinoIDE echt een %#@& IDE is, of ik kan er niet mee omgaan. Dat zal het wel zijn. Visual studio code is al heel veel beter, maar visual studio spant de kroon. Het geen wat Arduino wel erg mooi doet, is het opzetten van de toolchain. Bij sommige processoren ben je daar rustig een dag mee bezig.

Functies niet te groot maken en een duidelijke naam geven is essentieel. Door juiste namen te kiezen heb je praktisch geen commentaar meer nodig. Als ik commentaar schrijf dan is dat meestal omdat ik iets raars aan het doen ben wat toelichting nodig heeft. In dat geval kun je beter overwegen om je code te herzien. Tripple slash is wel erg handig, zeker in C# werkt dit heel goed.

Underscores in C gebruik ik wel eens om functies te groeperen: LCD_Print, LCD_Clear, ect. Stijl is verder een kwestie van smaak / gewenning natuurlijk. Microsoft deed heel lang (misschien nog wel) de eerste letter gebruiken om aan te duiden wat voor type een variabele is. Ik vermoed dat vroeger de IDE niet zo denderend was, maar tegenwoordig geeft iedere IDE wel aan wat voor type je variabele is.

int iSomeInteger;
float fSomeFloat;

@benleentje, dat is wel C++ geen C. Nu ben ik zelf ook wel voorstander van C++, maar het komt direct met een aantal uitdagingen zeker wat betreft microcontrollers.

@Blackdog, het beste wat je kan doen is veel oefenen. :) Alle programmeer vakken bij ons op school waren practica. Voor je cijfer was het altijd een opdracht maken. Soms eerst een uurtje een presentatie ofzo, maar altijd praktisch zelf bezig zijn.

@rew, de 'scheduler' die je even terug posten zou de oplossingsrichting zijn die ik zelf ook zo zou kiezen. Een puntje, hij houdt geen rekening met de overflow van millis. Deze is iedere 50 dagen volgens Arduino. Eenvoudig te fixen dat dan weer wel. :)

Wat betreft de indentering, ik merk dat CO hier iets gekkigs doet met tabs. Misschien eens iets voor een mod om naar te kijken?

PE2BAS
benleentje

Golden Member

@benleentje, dat is wel C++ geen C. Nu ben ik zelf ook wel voorstander van C++, maar het komt direct met een aantal uitdagingen zeker wat betreft microcontrollers.

Die discussie barste ook al los in ander topic waarin ik dat opperde.

Ja ik moet toegeven dat het heel uitdagend is maar dat is ook wel mijn niveau wat ik goed aankan.
Arduino bibliotheken zijn merendeel ook zelf C++ en het werken met objecten werk bij mij heel natuurlijk.
Dus het is iets wat mij goed bevallen is en waar ik veel aan heb gehad.

Wellicht heb jij hardbass een betere aanbeveling meer passen bij blackdog

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.

Ik ben zelf groot voorstander van C++. Maar je moet wel rekening houden met het dynamische RAM gedrag van C++. Een alternatieve cursus heb ik niet, nooit een cursus gedaan dus ik zou niet weten wat ik moet aanbevelen. :)

Mijn advies aan Blackdog, lekker blijven programmeren. Hoe meer je dit doet hoe beter je er in wordt. Dingen opzoeken online, er is heel veel informatie op internet. De community is ook erg groot, zeker met Arduino.

Als je iets leuk vind dan doe je het veel.
Doe je iets veel dan wordt je er beter in.
Ben je er goed in vind je het vaak ook leuk om te doen.

PE2BAS
blackdog

Golden Member

Hi,

Ik zoek verder naar een "soort" cursus die mij aanspreekt.
Ik zal de code die ik gisteren heb laten zien laten inspringen waar nodig.

De onderstaande code had ik al gezien in een aantal video's die ik vorige week bekeken had en zal het proberen te gaan toepassen zodat het duidelijk is of het om 16, 32 of 64 bit gaat.

c code:


uint64_t prevAmpTempMeasured = 0;
uint64_t prevPSUTempMeasured = 0;
uint64_t prevTrafoTempMeasured = 0;
uint64_t prevDisplayUpdated = 0;

Dank weer voor de input!

Inpakken van de koffer is nu even belangrijker. :-)
Maar ik blijf wel ondertussen jullie berichten lezen.

Groet,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.
benleentje

Golden Member

Op 21 april 2022 13:12:41 schreef hardbass:
Ik ben zelf groot voorstander van C++. Maar je moet wel rekening houden met het dynamische RAM gedrag van C++..

Dat hangt er ook sterk van af welke functie je gebruikt denk ik. Met een nano had ik daar denk ik wel last van werd strings ineens overschreven ben toen naar de veel grotere due gegaan en had er toen geen last meer van.

Ik vind het wel grappig de vorige discussie werd ik helemaal afgebrand omdat ik C++ voorstelde en toen werd er bij hoog en laag beweert dat C veel beter was. Wat beter is weet ik niet weet alleen dat C++ me na die cursus wel ineens goed bevalt, daarvoor had ik er ook veel problemen mee.

Ik zoek verder naar een "soort" cursus die mij aanspreekt.

Uiteraard het moet wel bij je passen. Ik denk dat een goede cursus wel veel problemen omtrent de grammatica in C weg neemt. Daar had ik vooral veel moeite mee van waarom en hoe werkt dat nu zo. Waarom soms dit en soms dat wat is het verschil of wat zijn de overeenkomsten die zijn na die cursus wel een eind weg.

Maar programmeren is ook vooral veel doen veel fouten maken dan slijt het er ook vanzelf in.

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.

Ahja beter of niet beter, het is anders :)

Zelf begin ik niet meer aan de kleinere processoren. Grotere kosten tegenwoordig net zoveel en je hoeft je niet in allerlei bochten te veringen om het toch te laten werken.

Ik vind OOP wel een heel stuk overzichtelijker. Mits het een beetje redelijk in elkaar zit natuurlijk.

PE2BAS

Op 20 april 2022 20:04:28 schreef hardbass:
Deel je code op in meerdere kleine functies. Sommige pleiten dat een stukje code nooit groter mag zijn dan op je scherm past.

Elk scherm heeft ander afmetingen. Ik zou gaan voor een (inhoudelijke) functie per (C/C++) functie:
- Als je 200 verschillende GPIO's moet instellen: Gebruik gerust 200 regels.
- Als je, afhankelijk van een input-schakelaar, LED1 of LED2 aan moet zetten: Gebruik gerust aparte functies voor LED1 en LED2 -control vanuit de if-then-else die de input decodeert.

Globale variabelen, probeer ze te voorkomen. Globale variabelen maken snel een grote brij van je code.

In het algemeen ben ik het daar mee eens, maar:
Er is in iedere embedded systeem een aantal variabelen die de core-state van het systeem zijn. Deze variabelen zijn continu aanwezig vanaf power-on tot power-off (en, indien relevant, overleven meestal een standy)

Die variabelen moeten globals kunnen zijn, het is onzinnig ze in main() als automatic te declareren (en bij Arduino kan dat niet eens, omdat automatics in loop() iedere keer opnieuw geinstantieerd worden), en alloceren met malloc() of new is de overhead echt niet waard.

Die variabelen moeten gewoon globals zijn. Eventueel georganiseerd (en gedocumenteerd) in een (of meerdere!) struct of class (met zijn eigen .h file).

Ook een buffer om print-strings te maken hoort hierbij. Zelden zal een MCU zo groot zijn dat het zin heeft die dynamisch te maken (en vaak heb je dan als een minimaal OS als FreeRTOS die het voor je regelt).

Verder ben ik persoonlijk voorstander van de stdint. Zo weet je altijd hoe groot je variabelen zijn ongeacht je processor. Dat maakt je code ook portable tussen verschillende processoren. Een int is op een classic Arduino 16 bits maar op een ESP32 32 bits. uint32_t en int32_t zijn altijd 32 bits.

Hear, Hear!!
Helemaal mee eens, met een uitzondering. Alle integers, waarbij 16 bit of meer goed is en het precieze aantal bits niet relevant (bijvoorbeeld loop-counters) gewoon als int declareren. int is het "default CPU type" en zal dus altijd het meest efficient zijn.

(Ja, op 8-bitters is int 16 bit omdat dat het minimum is. Nee, dat is niet het meest efficient. Dus als uit profiling blijkt dat op jouw 8-bitter een specifieke loop te traag is door het gebruik van 16-bits ints, dan mag je er een uint_8 van maken. Geen char!)

Op 21 april 2022 13:12:41 schreef hardbass:
Ik ben zelf groot voorstander van C++. Maar je moet wel rekening houden met het dynamische RAM gedrag van C++.

Als je kijkt naar Arduino, dan is wat ze daar aan C++ doen vooral C met classes. Classes (objecten) worden gebruikt als aangeklede structs (structs met functies) en meer niet.

Dat is zeker nuttig, maar de (voor microcontroller) gevaarlijke C++ features (multiple inheritance met virtual functies, new/delete) worden niet gebruikt.

blackdog

Golden Member

Hi,

Al weer een paar dagen in Nederland en nog zo gaar als boter van de jetlag...

Het beetje tijd dat ik beschikbaar had na de administratie, wat vooral voor klanten was, heb ik besteed aan het testen van microcontrolers die op mij lagen te wachten na terugkomst.

Twee microcontrolers heb ik getest om te zien of ze bruikbaar waren voor het project waar deze software voor is.
De eerste die ik teste was deze Seeeduno XIAO een leuke kleine microcontroler, net voldoende pinnen voor mijn toepassing.
De code wou wou niet goed lopen met deze controler, na wat uitzoekwerk blijkt dat Seeed de ADC driver heel anders (simpeler) heeft uitgevoerd als b.v. Teensy
of andere microcontroler bouwer.
Hierdoor kon ik de middeling e.d. niet instellen.

De tweede microcontroler ik teste is de Arduino RP2040 Connect.
Deze begon ik te testen met een 1.54 Inch Display met een ST7789 controler, de interface van dit display is SPI.
Die RP2040 is zo slecht op de SPI bus, een Arduino Nano verslaat hem.
Ik heb diverse instellingen aangepast, ook gekozen voor hardware SPI, mocht allemaal niet helpen.
Het display getest met de driver van Adafruit en de GFX library en in het voorbeeldscript de instellingen aangepast.

Zelfde Display aan een Teensy-LC gehangen en Bingo! die toch een stuk minder krachtige microcontroler heeft.

Dus... ik duw er gewoon een Teensy-4 in, hij is uiteindelijk klein genoeg en krachtig genoeg voor mijn toepassing.
Ik had gehoopt met het nieuwere spul te kunnen werken voor dit project.

Ik plan deze week de code een beetje te kunnen opschonen zoals jullie hebben aangegeven, beetje werken aan de mechanische opbouw en het tekenen van het frontpaneel.
Tot snel.

Groet,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.