DS18B20 en TMP37 Kalibrator


blackdog

Golden Member

Hi,

Update van het schema, klik voor de grote versie.

https://www.bramcam.nl/NA/DS18B20-TMP37-Kal/DS18B20-TMP37-Kal-77-Klein.png

.
Wel al begonen aan de Excel lijst maar niet voldoene tijd om het nu al af te hebben, komt morgen wel.

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

De pull-up aan het display is met maar 1 device aan de SPI bus niet echt nodig, maar het voorkomt dat er vreemde data op het display komt.
(en het is 'good practice': bij meerdere SPI devices aan de bus is het wel verplicht.)

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com
blackdog

Golden Member

Hi,

Schema is weer bijgewerkt en de Excel lijst heb ik nu ook de eerste versie van, beide laat ik hieronder zien.
Ik heb geprobeerd het schema zo leesbaar mogelijk te maken.
Er is al zeer veel geschoven met de positie van de componenten en de beschrijvingen die in het schema staan.
Ook heb ik als laatst kleine pijltjes in verschillende lijnen aangebracht om de richting aan te geven va nde stromen of het signaal.
De i2c bus staat nu ook in het schema, hiervan is nog niet zeker of ik deze ook echt ga gebruiken, eerst maar zien of ik het geheel zoals het hier nu op schema staat functioneel is.

Eerst weer het klikbase schema in de laatste versie van vandaag betreffende de Teensy controler.
https://www.bramcam.nl/NA/DS18B20-TMP37-Kal/DS18B20-TMP37-Kal-100b-Klein.png

.
Dit is de laatste versie van de electronica in het oventje.
https://www.bramcam.nl/NA/DS18B20-TMP37-Kal/DS18B20-TMP37-Kal-101.png

.
Dit is de Excel lijst, die tot vanmiddag up to date is en hij is klikbaar.
https://www.bramcam.nl/NA/DS18B20-TMP37-Kal/DS18B20-TMP37-Kal-100a-Klein.png

.
Met de software ben ik ook al bezig geweest, maar nog niet klaar met wat extra testen voor ik de vraag stel waar het een en ander zou kunnen vastlopen.

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
blackdog

Golden Member

Hi,

Nu de software die ik niet werkend krijg voor het aansturen van de oven.

Hieronder de errors die ik krijg, maar hij compileerd wel en werkt niet. ;)

c code:


C:\Users\xxxxxx\Documents\Arduino\Teesy-LC-ILI9341-10\Teesy-LC-ILI9341-10.ino: In function 'void loop()':

C:\Users\xxxxxx\Documents\Arduino\Teesy-LC-ILI9341-10\Teesy-LC-ILI9341-10.ino:217:9: warning: unused variable 'Button1' [-Wunused-variable]
    byte Button1 = Rotary_SW1.Button();
         ^

C:\Users\xxxxxx\Documents\Arduino\Teesy-LC-ILI9341-10\Teesy-LC-ILI9341-10.ino:218:9: warning: unused variable 'Button2' [-Wunused-variable]
    byte Button2 = Rotary_SW2.Button();
         ^

C:\Users\xxxxxx\Documents\Arduino\Teesy-LC-ILI9341-10\Teesy-LC-ILI9341-10.ino:219:9: warning: unused variable 'Button3' [-Wunused-variable]
    byte Button3 = Rotary_SW3.Button();
         ^

C:\Users\xxxxxx\Documents\Arduino\Teesy-LC-ILI9341-10\Teesy-LC-ILI9341-10.ino:221:9: warning: unused variable 'Clicks1' [-Wunused-variable]
    int  Clicks1 = Rotary_SW1.Clicks();
         ^

C:\Users\xxxxxx\Documents\Arduino\Teesy-LC-ILI9341-10\Teesy-LC-ILI9341-10.ino:222:9: warning: unused variable 'Clicks2' [-Wunused-variable]
    int  Clicks2 = Rotary_SW2.Clicks();
         ^

C:\Users\xxxxxx\Documents\Arduino\Teesy-LC-ILI9341-10\Teesy-LC-ILI9341-10.ino:223:9: warning: unused variable 'Clicks3' [-Wunused-variable]
    int  Clicks3 = Rotary_SW3.Clicks();
         ^

De schets gebruikt 22880 bytes (36%)  programma-opslagruimte. Maximum is 63488 bytes.
Globale variabelen gebruiken 2104 bytes (25%) van het dynamisch geheugen. Resteren 6088 bytes voor lokale variabelen. Maximum is 8192 bytes.

En hieronder mijn code, met veel zaken uitgeschakeld, als ik de code voor het uitlezen van de deKees print uitzet, werkt mijn code voor het uitlezen van de drukknopjes zonder problemen.
Ook de kaders springen heen en weer als ik de temperatuur functie gebruik, dus ik zie dan geen errors.
Ik ga er niet vanuit dat omdat het dan goed werkt, het goede code zou moeten zijn. :+

De code met alleen de JC_Button library is dus OK, wil ik ook de software van deKees gaan gebruiken, dan worden somminge delen van het scherm niet meer geschreven, en defunctie van de serieel monitor gaat dan ook plat.

Wat ik heb gedaan is het vergelijken van de JC_Button.ccp, LC_Button.h en de I@C_Rotary_003.h met elkaar vergeleken of daar code in zat die elkaar in de weg zou zitten, Ja dus denk ik, maar ik kan het niet vinden, jullie wel?
Ik zal de Library files hier ook in het topic opnemen.

Mijn oven code

c code:



#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <PID_v1.h>             // NOG NIET IN GEBRUIK
#include <JC_Button.h>          // https://github.com/JChristensen/JC_Button
#include "I2C_Rotary_003.h"     // deKees i2c encoder library


// Extra font voor het display
#include <Fonts/FreeSans9pt7b.h>

//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS-10, TFT_DC-9, TFT_MOSI-11, TFT_CLK-13, TFT_RST-8, TFT_MISO-12);
Adafruit_ILI9341 tft = Adafruit_ILI9341(10, 9, 11, 13, 8, 12);


// Button variabelen 
ToggleButton                    // define the buttons
    btn1(1),                    // this button's initial state is off
    btn2(2),                    // this button's initial state is off
    btn3(3, true);              // this button's initial state is on
// *  Button variabelen 


// Instellingen voor de oven temperatuur
//    int tp_low = 37;            // Schakelpunt voor de PreHeat 40C oven temperatuur, NOG NIET IN GEBRUIK
//    int tp_high = 42;           // Schakelpunt voor de PreHeat 45C oven temperatuur, NOG NIET IN GEBRUIK
//
//    int t40 = 40;               // 40C oven temperatuur, NOG NIET IN GEBRUIK
//    int t45 = 45;               // 45C oven temperatuur, NOG NIET IN GEBRUIK
//
//    int t40_corr = 0;           // Correctie voor 40C oven temperatuur, NOG NIET IN GEBRUIK
//    int t45_corr = 0;           // correctie voor 45C oven temperatuur, NOG NIET IN GEBRUIK
// * Instellingen voor de oven temperatuur


// Declare 3 rotary objects, all use the same I2C address, but different switch numbers
    I2C_Rotary Rotary_SW1(0xA0, 1);  // SW1
    I2C_Rotary Rotary_SW2(0xA0, 2);  // SW2
    I2C_Rotary Rotary_SW3(0xA0, 3);  // SW3
// * Declare 3 rotary objects, all use the same I2C address, but different switch numbers





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


// Teensy SPI Settings
//    SPI.begin();
//    SPI.setClockDivider(SPI_CLOCK_DIV2);
// * Teensy SPI Settings

  
//  Initialize the button objects
    btn1.begin();
    btn2.begin();
    btn3.begin();
    
    // set the LED pins as outputs
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    
    // show the initial states
    digitalWrite(4, btn1.toggleState());
    digitalWrite(5, btn2.toggleState());
    digitalWrite(6, btn3.toggleState());
// * Initialize the button objects


//  Initialize pinmode voor sensor power supply switching
    pinMode(7, OUTPUT);
    digitalWrite(7, LOW);
//  * Initialize pinmode voor sensor power supply switching


//  Initialize tft screen  
    tft.begin();
    tft.setRotation(1); // Horizontaal
    tft.fillScreen(ILI9341_BLACK);
// * Initialize tft screen  


// Lijnen en kaders die altijd op het scherm staan
     tft.drawRoundRect(168, 0, 150, 21, 4, 0x07E0);           // Groen kader bovenste tekst regel
     tft.fillRect(0, 75, 320, 58, 0x001F);                    // Blauwe kader midden in beeld
     tft.fillRect(0, 23, 320, 4, ILI9341_GREEN);              // Dikke lijn onder bovenste tekstregel
     tft.fillRect(0, 57, 320, 4, ILI9341_GREEN);              // Dikke lijn onder Set temperature     


     tft.drawLine(0, 75, 320, 75, ILI9341_WHITE);
     tft.drawLine(0, 132, 320, 132, ILI9341_WHITE);
// * Lijnen en kaders die altijd op het scherm staan


// Tekst die altijd in beeld staat
     tft.setFont(&FreeSans9pt7b);
     tft.setTextColor(0x03EF);  tft.setTextSize(0);

     tft.setCursor(2, 16);
     tft.println("NA-TMP-cal   V1.0");
    
     tft.setCursor(173, 16);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("Sensor Calibrator");

     tft.setTextColor(ILI9341_GREEN);  tft.setTextSize(1);
     tft.setCursor(10, 48);
     tft.println("Set Temperature:");

     tft.setCursor(171, 48);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(40);

     tft.setCursor(240, 48);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(45);

     // Set Celcius karakter op het scherm voor temp-40
     tft.fillCircle(196, 38, 2, 0xFFFF); 
     tft.setCursor(200, 47);
     tft.println("C");

     // Set Celcius karakter op het scherm voor temp-45
     tft.fillCircle(265, 38, 2, 0xFFFF); 
     tft.setCursor(269, 48);
     tft.println("C");

     // Set de tekst op beeld van de oven NTC
     tft.fillCircle(114, 113, 2, 0xFFFF);
     tft.setCursor(5, 123);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("NTC: 40,564  C");
    
     // Set de tekst op beeld de oven T-SIC sensor
     tft.fillCircle(299, 113, 2, 0xFFFF);
     tft.setCursor(180, 123);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("T-SIC: 40,561  C");

     // Set de tekst op beeld voor de P waarde
     tft.setCursor(0, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("P = ");

     // Set de tekst op beeld voor de I waarde
     tft.setCursor(130, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("i = ");

     // Set de tekst op beeld voor de D waarde
     tft.setCursor(250, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("D = ");
     
// * Tekst die altijd in beeld staat


// Rotary encoder Setup
   // Set parameters for Rotary_SW1
   Rotary_SW1.m_MinValue = 0.0;
   Rotary_SW1.m_MaxValue = 500.0;
   Rotary_SW1.m_StepSize = 1.0;
   Rotary_SW1.m_Value    = 0.0;
   Rotary_SW1.SetDirection(0);
   Rotary_SW1.SetAccelleration(0);

   // Set parameters for Rotary_SW2
   Rotary_SW2.m_MinValue = 0.0;
   Rotary_SW2.m_MaxValue = 500.0;
   Rotary_SW2.m_StepSize = 1.0;
   Rotary_SW2.m_Value    = 0.0;
   Rotary_SW2.SetDirection(1);
   Rotary_SW2.SetAccelleration(0);

   // Set parameters for Rotary_SW3
   Rotary_SW3.m_MinValue = 0.0;
   Rotary_SW3.m_MaxValue = 500.0;
   Rotary_SW3.m_StepSize = 1.0;
   Rotary_SW3.m_Value    = 0.0;
   Rotary_SW3.SetDirection(0);
   Rotary_SW3.SetAccelleration(0);
// * Rotary encoder Setup


}


// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void loop(){
    // read the buttons
    btn1.read();
    btn2.read();
    btn3.read();


    // if button state changed, update the LEDs
    if (btn1.changed()) digitalWrite(4, btn1.toggleState());
    if (btn2.changed()) digitalWrite(5, btn2.toggleState());
    if (btn3.changed()) digitalWrite(6, btn3.toggleState());


//  tijdelijke debug serial commands
    Serial.print("Drukknop-1   ");  Serial.println(btn1.toggleState());
    Serial.print("Drukknop-2   ");  Serial.println(btn2.toggleState());
    Serial.print("Drukknop-3   ");  Serial.println(btn3.toggleState());
// * tijdelijke debug serial commands


// Scan status of the deKees rotary encoders
   byte Button1 = Rotary_SW1.Button();
   byte Button2 = Rotary_SW2.Button();
   byte Button3 = Rotary_SW3.Button();

   int  Clicks1 = Rotary_SW1.Clicks();
   int  Clicks2 = Rotary_SW2.Clicks();
   int  Clicks3 = Rotary_SW3.Clicks();
// * Scan status of the deKees rotary encoders



// Meet de oven temperatuur en als de oven op temperatuur is plaatst Oven Ready op het scherm

//    if



// * Meet de oven temperatuur en als de oven op temperatuur is plaatst Oven Ready op het scherm

// Plaatst kader om de gekozen temperatuur waarde.
     if ((btn1.toggleState()) == 0) {                                                // Controleer de Drukknop-1 status en voer actie uit, bij status "0" plaats kader om 40C waarde op het scherm
     tft.drawRoundRect(237, 31, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 45C
     tft.drawRoundRect(236, 30, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 45C
     tft.drawRoundRect(168, 31, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 40C
     tft.drawRoundRect(167, 30, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 40C
  }
     else {
     tft.drawRoundRect(168, 31, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 40C
     tft.drawRoundRect(167, 30, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 40C
     tft.drawRoundRect(237, 31, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 45C
     tft.drawRoundRect(236, 30, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 45C
  }



     tft.setCursor(20, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
//     tft.println(Clicks1);                                                          // plaats "P" waarde van rotary encoder-1 op het scherm

     // Set de tekst op beeld voor de D waarde
     tft.setCursor(150, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
 //    tft.println(Clicks2);                                                          // plaats "I" waarde van rotary encoder-2 op het scherm

     // Set de tekst op beeld voor de D waarde
     tft.setCursor(270, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
 //    tft.println(Clicks3);                                                          // plaats "D" waarde van rotary encoder-2 op het scherm


   // Just write the result to the serial port
//   if(Knop1)
//   {  Serial.print( F("SW1 : Knop = ") );
//      Serial.println(Button1);
//      Serial.println();
//   }
//   if(Knop2)
//   {  Serial.print( F("SW2 : Knop = ") );
//      Serial.println(Button2);
//      Serial.println();
//   }
//   if(Knop3)
//   {  Serial.print( F("SW3 : Knop = ") );
//      Serial.println(Button3);
//      Serial.println();
//   }
   // * Just write the result to the serial port



Serial.println(btn1.toggleState());

delay(3);
}

De JC_Button.ccp file

c code:


// Arduino Button Library
// https://github.com/JChristensen/JC_Button
// Copyright (C) 2018 by Jack Christensen and licensed under
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html

#include "JC_Button.h"

/*----------------------------------------------------------------------*
/ initialize a Button object and the pin it's connected to.             *
/-----------------------------------------------------------------------*/
void Button::begin()
{
    pinMode(m_pin, m_puEnable ? INPUT_PULLUP : INPUT);
    m_state = digitalRead(m_pin);
    if (m_invert) m_state = !m_state;
    m_time = millis();
    m_lastState = m_state;
    m_changed = false;
    m_lastChange = m_time;
}

/*----------------------------------------------------------------------*
/ returns the state of the button, true if pressed, false if released.  *
/ does debouncing, captures and maintains times, previous state, etc.   *
/-----------------------------------------------------------------------*/
bool Button::read()
{
    uint32_t ms = millis();
    bool pinVal = digitalRead(m_pin);
    if (m_invert) pinVal = !pinVal;
    if (ms - m_lastChange < m_dbTime)
    {
        m_changed = false;
    }
    else
    {
        m_lastState = m_state;
        m_state = pinVal;
        m_changed = (m_state != m_lastState);
        if (m_changed) m_lastChange = ms;
    }
    m_time = ms;
    return m_state;
}

/*----------------------------------------------------------------------*
 * isPressed() and isReleased() check the button state when it was last *
 * read, and return false (0) or true (!=0) accordingly.                *
 * These functions do not cause the button to be read.                  *
 *----------------------------------------------------------------------*/
bool Button::isPressed()
{
    return m_state;
}

bool Button::isReleased()
{
    return !m_state;
}

/*----------------------------------------------------------------------*
 * wasPressed() and wasReleased() check the button state to see if it   *
 * changed between the last two reads and return false (0) or           *
 * true (!=0) accordingly.                                              *
 * These functions do not cause the button to be read.                  *
 *----------------------------------------------------------------------*/
bool Button::wasPressed()
{
    return m_state && m_changed;
}

bool Button::wasReleased()
{
    return !m_state && m_changed;
}

/*----------------------------------------------------------------------*
 * pressedFor(ms) and releasedFor(ms) check to see if the button is     *
 * pressed (or released), and has been in that state for the specified  *
 * time in milliseconds. Returns false (0) or true (!=0) accordingly.   *
 * These functions do not cause the button to be read.                  *
 *----------------------------------------------------------------------*/
bool Button::pressedFor(uint32_t ms)
{
    return m_state && m_time - m_lastChange >= ms;
}

bool Button::releasedFor(uint32_t ms)
{
    return !m_state && m_time - m_lastChange >= ms;
}

/*----------------------------------------------------------------------*
 * lastChange() returns the time the button last changed state,         *
 * in milliseconds.                                                     *
 *----------------------------------------------------------------------*/
uint32_t Button::lastChange()
{
    return m_lastChange;
}

En dit is de JC_Button.h file

c code:


// Arduino Button Library
// https://github.com/JChristensen/JC_Button
// Copyright (C) 2018 by Jack Christensen and licensed under
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html

#ifndef JC_BUTTON_H_INCLUDED
#define JC_BUTTON_H_INCLUDED

#include <Arduino.h>

class Button
{
    public:
        // Button(pin, dbTime, puEnable, invert) instantiates a button object.
        //
        // Required parameter:
        // pin      The Arduino pin the button is connected to
        //
        // Optional parameters:
        // dbTime   Debounce time in milliseconds (default 25ms)
        // puEnable true to enable the AVR internal pullup resistor (default true)
        // invert   true to interpret a low logic level as pressed (default true)
        Button(uint8_t pin, uint32_t dbTime=25, uint8_t puEnable=true, uint8_t invert=true)
            : m_pin(pin), m_dbTime(dbTime), m_puEnable(puEnable), m_invert(invert) {}

        // Initialize a Button object and the pin it's connected to
        void begin();

        // Returns the current debounced button state, true for pressed,
        // false for released. Call this function frequently to ensure
        // the sketch is responsive to user input.
        bool read();

        // Returns true if the button state was pressed at the last call to read().
        // Does not cause the button to be read.
        bool isPressed();

        // Returns true if the button state was released at the last call to read().
        // Does not cause the button to be read.
        bool isReleased();

        // Returns true if the button state at the last call to read() was pressed,
        // and this was a change since the previous read.
        bool wasPressed();

        // Returns true if the button state at the last call to read() was released,
        // and this was a change since the previous read.
        bool wasReleased();

        // Returns true if the button state at the last call to read() was pressed,
        // and has been in that state for at least the given number of milliseconds.
        bool pressedFor(uint32_t ms);

        // Returns true if the button state at the last call to read() was released,
        // and has been in that state for at least the given number of milliseconds.
        bool releasedFor(uint32_t ms);

        // Returns the time in milliseconds (from millis) that the button last
        // changed state.
        uint32_t lastChange();

    private:
        uint8_t m_pin;          // arduino pin number connected to button
        uint32_t m_dbTime;      // debounce time (ms)
        bool m_puEnable;        // internal pullup resistor enabled
        bool m_invert;          // if true, interpret logic low as pressed, else interpret logic high as pressed
        bool m_state;           // current button state, true=pressed
        bool m_lastState;       // previous button state
        bool m_changed;         // state changed since last read
        uint32_t m_time;        // time of current state (ms from millis)
        uint32_t m_lastChange;  // time of last state change (ms)
};

// a derived class for a "push-on, push-off" (toggle) type button.
// initial state can be given, default is off (false).
class ToggleButton : public Button
{
    public:
    
        // constructor is similar to Button, but includes the initial state for the toggle.
        ToggleButton(uint8_t pin, bool initialState=false, uint32_t dbTime=25, uint8_t puEnable=true, uint8_t invert=true)
            : Button(pin, dbTime, puEnable, invert), m_toggleState(initialState) {}

        // read the button and return its state.
        // should be called frequently.
        bool read()
        {
            Button::read();
            if (wasPressed())
            {
                m_toggleState = !m_toggleState;
                m_changed = true;
            }
            else
            {
                m_changed = false;
            }
            return m_toggleState;
        }

        // has the state changed?
        bool changed() {return m_changed;}

        // return the current state
        bool toggleState() {return m_toggleState;}

    private:
        bool m_toggleState;
        bool m_changed;
};
#endif

En als laatste de library file van deKees genaamd: I2C_Rotary_003.h

c code:


#ifndef I2C_ROTARY_003_01
#define I2C_ROTARY_003_01


#include <Wire.h>

class I2C_Rotary
{
public:

   // Id = 1 .. 3
   // Set default values:
   I2C_Rotary(byte NewAddress, byte NewId)
   {  m_Address = NewAddress;
      m_Id      = NewId;

      // Set defaults
      m_Value    =    0.0;
      m_MinValue =    0.0;
      m_MaxValue = 1000.0;
      m_StepSize =    1.0;
   }

   // Check Knop Status
   //  - 0 : Not pressed
   //  - 1 : Short press
   //  - 2 : Long press
   byte Knop()
   {  const byte NrBytes = 3;
      byte Response[NrBytes] = { 0 };
      if( ReadRegister((byte)(0xB0 + m_Id), Response, NrBytes) >= NrBytes )
      {  return Response[2];
      }
      else
      {  // Xmit failed for some reason. See m_XmitStatus.
         return 0;
      }
   }

   // Check rotation.
   // And update m_Value.
   int Clicks()
   {  const byte NrBytes = 5;
      byte Response[NrBytes] = { 0 };
      if( ReadRegister((byte)(0xC0 + m_Id), Response, NrBytes) >= NrBytes )
      {
         // Calculate NrClicks
         int NrClicks = (Response[2] << 8)
                      + (Response[3] << 0);

         // Update Value
         m_Value += NrClicks * m_StepSize;

         // Apply limits
         if(m_Value < m_MinValue)
         {  m_Value = m_MinValue;
         }
         if(m_Value > m_MaxValue)
         {  m_Value = m_MaxValue;
         }

         return NrClicks;
      }
      else
      {  // Xmit failed for some reason. See m_XmitStatus.
         return 0;
      }
   }

   // To set direction of rotary movement:
   //   direction = 0  : A leads B
   //   direction = 1  : B leads A
   void SetDirection(byte NewDirection)
   {  WriteRegister((byte)(0x10 + m_Id), NewDirection);   // MsgId : Set direction
      delay(20); // Target needs some time to update EEPROM
   }

   // To set accelleration of rotary movement:
   //   acceleration = 0  : No
   //   acceleration = 1  : Yes
   void SetAccelleration(byte Accelleration)
   {  WriteRegister((byte)(0x20 + m_Id), Accelleration);  // MsgId : Set Accelleration
      delay(20); // Target needs some time to update EEPROM
   }

   // To set a new I2C address
   // - But perhaps the slave has already switched to the new address
   byte ChangeAddress(byte OldAddress, byte NewAddress)
   {
      byte Response[3];  // Little buffer for response messages

      // First check new address
      m_Address = NewAddress;
      if( ReadRegister((byte)(0xF0), Response, 3) == 3 )   // MsgId : I2C address
      {  if(Response[2] == NewAddress)
         {  return 0;  // New adress already active
         }
         else
         {  return 1;  // Something is present on this address, but response is wrong
         }
      }
      else
      {  // No response on New address yet. Send update to old address
         m_Address = OldAddress;
         WriteRegister((byte)0xF0, NewAddress);

         // controller needs some time to update the EEprom
         delay(20);

         // Check if it hs worked
         m_Address = NewAddress;
         if(    (ReadRegister( (byte)0xF0, Response, 3 ) == 3)   // MsgId : I2C address
             && (Response[2] == NewAddress) )
         {  return 2;
         }
         else
         {  return 3;
         }
      }
   }

   void WriteRegister(byte Register, byte Value)
   {  Wire.beginTransmission(m_Address >> 1);
      Wire.write(Register);  // MsgId : Set Accelleration
      Wire.write(Value);
      m_XmitStatus = Wire.endTransmission(true);
   }

   byte ReadRegister(byte Register, byte *pBuffer, byte NrBytes)
   {  Wire.beginTransmission((byte)(m_Address >> 1));
      Wire.write(Register);
      m_XmitStatus = Wire.endTransmission(false);

      if(m_XmitStatus == 0)
      {  m_RecvCount = Wire.requestFrom((byte)(m_Address >> 1), NrBytes);
         for (byte i = 0; i < m_RecvCount; i++)
         {  pBuffer[i] = Wire.read();
         }
         return m_RecvCount;
      }
      else
      {  // Xmit failed for some reason.
         // - See m_XmitStatus.
         return 0;
      }
   }

   byte  m_Address;    // I2C address of rotary controller
   byte  m_Id;         // Switch Nr 1 .. 3

   float m_Value;      // Rotary status

   float m_MinValue;   // Limits
   float m_MaxValue;
   float m_StepSize;

   byte  m_XmitStatus; // Communicatio0n status
   byte  m_RecvCount;  //
};

#endif

Alle hulp is welkom :-)

Dank,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

Wist ik ook niet, maar het lijkt erop dat de I2C library van de Teensy afwijkt, omdat die zijn I2C verschillende pinnen geconfigureerd kan hebben.

Het kan zomaar zijn dat de I2C nu op de verkeerde pinnen wordt uitgestuurd.

De Teensy I2C library heeft een stel extra funkties die misschien het probleem oplossen. :

code:


   Wire.setSDA(18);
   Wire.setSCL(19);

Kun je zo toevoegen aan de setup() denk ik.

Kan het misschien zijn dat de verkeerde wire library nu loopt?
Die teensy komt in een flink aantal varianten, en misschien heb je een speciale versie nodig voor de teensy-LC.

Ik zou eens proberen met alleen de rotary, en kijken of de goede pinnen aangestuurd worden. Zoniet, dan wordt het zoeken naar de juiste library.

blackdog

Golden Member

Hi deKees,

De regels toegevoegd aan de setup, pinnummers gecontroleerd maar nog steeds de zelfde foutmelding en de code loopt nog steeds niet.
Ik vind het vreemd dat de serial monitor niet werkt en ook delen van het scherm niet geschreven worden.

Daarna jouw testcode gedraaid, nop alleen onzinwaarden komt daar uit.
De drukknopjes gaan wel goed geven alle drie een 1 in beeld via de serieele monitor.

Wat info hoe het staat ingesteld bij jouw testfile voor het printje.
De schakelaars alledrie het zelfde ingesteld behalve de MaxValue voor het onderscheid.

c code:


void setup() 
{
   Wire.begin();
   Wire.setSDA(18);
   Wire.setSCL(19);
   
   Serial.begin(38400);

   Serial.println();
   Serial.println( F("Turn a rotary an see what happens") );
   Serial.println();
   
   // Set parameters for Rotary_SW1
   Rotary_SW1.m_MinValue =   0;
   Rotary_SW1.m_MaxValue =   999;
   Rotary_SW1.m_StepSize =   1;
   Rotary_SW1.m_Value    =   0;
   Rotary_SW1.SetDirection(1);
   Rotary_SW1.SetAccelleration(0);

   // Set parameters for Rotary_SW2
   Rotary_SW2.m_MinValue =  0;
   Rotary_SW2.m_MaxValue =  888;
   Rotary_SW2.m_StepSize =  1;
   Rotary_SW2.m_Value    =  0;
   Rotary_SW2.SetDirection(1);
   Rotary_SW2.SetAccelleration(0);

   // Set parameters for Rotary_SW3
   Rotary_SW3.m_MinValue =  0;
   Rotary_SW3.m_MaxValue =  777;
   Rotary_SW3.m_StepSize =  1;
   Rotary_SW3.m_Value    =  0;
   Rotary_SW3.SetDirection(1);
   Rotary_SW3.SetAccelleration(0);
}

c code:


SW1 : Clicks = 1
SW1 : Value  = 2.00

SW1 : Clicks = 1
SW1 : Value  = 3.00

SW1 : Clicks = 1
SW1 : Value  = 4.00

SW1 : Clicks = 1
SW1 : Value  = 5.00

SW1 : Clicks = 1
SW1 : Value  = 6.00

SW1 : Clicks = 65535 <= hier 1x terug gedraaid!
SW1 : Value  = 999.00


SW2 : Clicks = 1
SW2 : Value  = 1.00

SW2 : Clicks = 1
SW2 : Value  = 2.00

SW2 : Clicks = 1
SW2 : Value  = 3.00

SW2 : Clicks = 1
SW2 : Value  = 4.00

SW2 : Clicks = 1
SW2 : Value  = 5.00

SW2 : Clicks = 1
SW2 : Value  = 6.00

SW2 : Clicks = 65535 <= hier 1x terug gedraaid!

SW2 : Value  = 888.00


SW3 doet ongeveer het zelfde...

Het lijkt goed mis te gaan bij het tellen, zou dat kunnen komen omdat het printje op 3.3V draait, dat zou moeten kunnen werken volgens de documentatie.

Oja, de laatste library van Teensy gebruikt voor i2c en de standaard Wire ook geprobeerd.

Groet en dank,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

Hi Bram,

Heeft niks met de spanning te maken.
Maar komt doordat de teensy een ARM is en 32-bit registers heeft.
De library denkt nog in 16-bit integers.

65535 is 0xFFFF = -1 op een Uno/Nano, maar dus niet in een Teensy.

In I2C_Rotary_003.h :

code:


 int Clicks()
   {  const byte NrBytes = 5;
      byte Response[NrBytes] = { 0 };
      if( ReadRegister((byte)(0xC0 + m_Id), Response, NrBytes) >= NrBytes )
      {
         // Calculate NrClicks
         int NrClicks = (Response[2] << 8)
                      + (Response[3] << 0);

Kun je het type van NrClicks veranderen naar 'int16_t' (of 'short int'):

code:


         int16_t NrClicks = (Response[2] << 8)
                          + (Response[3] << 0);

Maar dat betekent wel dat I2C werkt, en geeft nog geen verklaring voor de andere problemen.

blackdog

Golden Member

Werkt voor de test file van jou!!! _/-\o_
Morgen het in mijn code testen.

Dank,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
blackdog

Golden Member

Morge, :-)

De Rotary code van de deKees library werkte ook in mijn code,
alleen het was natuurlijk een chaos op het scherm bij het weergeven van de Counter waarde omdat de tekst heen en weer springt door de getal grote.

Dat heb ik opgelost door te kijken hoelang maximaal de tekst is en een vergelijking te doen of de waarde van de desbetreffende Counter is veranderd.
Is de waarde veranderd, dan schrijf ik eerst een zwart blokje op het scherm op de positie van de oude tekst en dan de nieuwe Counter waarde.
De P.I.D. waarde onder op het scherm is maar tijdelijk en alleen voor het makkelijk tunen van de oven, daarna zet ik de P.I.D. waarde vast in de code.

Hoe doen jullie dat met tekst die je regelmatig veranderd op het scherm?
Grote blokken wissen/overschrijven is in ieder geval inefficent en kost daardoor veel looptijd.

deKees nog wel een vraag, hieronder een stukje uit de code die ik gebruik, byte ButtonX kan ik uit zetten, deze gebruik ik niet.
als ik dit ook bij int ClicksX doe, dan krijg ik een error, laat ik het staan, dan krijg ik een compiler opmerking dat ClicksX niet gebruikt wordt.
Het gaat mij in dit project alleen om de counter waarde, de andere waarde zijn in dit project niet nodig, moet ik de compiler error gewoon negeren?

c code:


// Scan status of the deKees rotary encoders
//   byte Button1 = Rotary_SW1.Button();
//   byte Button2 = Rotary_SW2.Button();
//   byte Button3 = Rotary_SW3.Button();
//
   int  Clicks1 = Rotary_SW1.Clicks();
   int  Clicks2 = Rotary_SW2.Clicks();
   int  Clicks3 = Rotary_SW3.Clicks();
// * Scan status of the deKees rotary encoders

c code:


warning: unused variable 'Clicks1' [-Wunused-variable]
    int  Clicks1 = Rotary_SW1.Clicks();
         ^

Dit is nu de Loop die werkt zoals ik het wil.

c code:


void loop(){
    // read the buttons
    btn1.read();
    btn2.read();
    btn3.read();


    // if button state changed, update the LEDs
    if (btn1.changed()) digitalWrite(4, btn1.toggleState());
    if (btn2.changed()) digitalWrite(5, btn2.toggleState());
    if (btn3.changed()) digitalWrite(6, btn3.toggleState());


// Scan status of the deKees rotary encoders
//   byte Button1 = Rotary_SW1.Button();
//   byte Button2 = Rotary_SW2.Button();
//   byte Button3 = Rotary_SW3.Button();
//
   int  Clicks1 = Rotary_SW1.Clicks();
   int  Clicks2 = Rotary_SW2.Clicks();
   int  Clicks3 = Rotary_SW3.Clicks();
// * Scan status of the deKees rotary encoders


// Meet de oven temperatuur en als de oven op temperatuur is plaatst Oven Ready op het scherm
// Hier komt de volgende te testen code
// * Meet de oven temperatuur en als de oven op temperatuur is plaatst Oven Ready op het scherm


// Plaatst kader om de gekozen temperatuur waarde.
     if ((btn1.toggleState()) == 0) {                                                // Controleer de Drukknop-1 status en voer actie uit, bij status "0" plaats kader om 40C waarde op het scherm
     tft.drawRoundRect(237, 31, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 45C
     tft.drawRoundRect(236, 30, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 45C
     tft.drawRoundRect(168, 31, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 40C
     tft.drawRoundRect(167, 30, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 40C
  }
     else {
     tft.drawRoundRect(168, 31, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 40C
     tft.drawRoundRect(167, 30, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 40C
     tft.drawRoundRect(237, 31, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 45C
     tft.drawRoundRect(236, 30, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 45C
  }


// Plaats rotary encoder counter waarde op het display
     // Set de tekst op beeld voor de P waarde
     if ((Rotary_SW1.m_Value) != SW1_Old)
     {
     tft.fillRect(35, 223, 60, 20, ILI9341_BLACK);                                   // Overschrijft oude waarde met zwart blokje
     tft.setCursor(34, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(Rotary_SW1.m_Value, 0);                                             // plaats "P" waarde van rotary encoder-1 op het scherm
     SW1_Old = (Rotary_SW1.m_Value);
     }

     // Set de tekst op beeld voor de I waarde
     if ((Rotary_SW2.m_Value) != SW2_Old)
     {
     tft.fillRect(149, 223, 60, 20, ILI9341_BLACK);                                   // Overschrijft oude waarde met zwart blokje
     tft.setCursor(150, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(Rotary_SW2.m_Value, 0);                                              // plaats "I" waarde van rotary encoder-2 op het scherm
     SW2_Old = (Rotary_SW2.m_Value);
     }
     
     // Set de tekst op beeld voor de D waarde
     if ((Rotary_SW3.m_Value) != SW3_Old)
     {
     tft.fillRect(264, 223, 60, 20, ILI9341_BLACK);                                   // Overschrijft oude waarde met zwart blokje     
     tft.setCursor(265, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(Rotary_SW3.m_Value, 0);                                              // plaats "D" waarde van rotary encoder-2 op het scherm
     SW3_Old = (Rotary_SW3.m_Value);
     }
// * Plaats rotary encoder counter waarde op het display

}
Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

code:


   int  Clicks1 = Rotary_SW1.Clicks();

De functie Clicks() gaat de clicks via I2C ophalen bij de rotary controller, en gebruikt die waarde om de Rotary_SW1.m_Value aan te passen. Dus als je die niet meer aanroept dan werkt het niet meer.

Als je de ClicksX niet nodig hebt hoef je die niet op te slaan. Dan is alleen aanroepen van de Clicks() functie voldoende:

code:


   Rotary_SW1.Clicks();
   Rotary_SW2.Clicks();
   Rotary_SW3.Clicks();

Je kunt ook de ClicksX 'gebruiken' zonder ze echt te gebruiken.

code:


   Clicks1;
   Clicks2;
   Clicks3;

Dat heeft geen effect en kost ook geen code ruimte, maar is wel genoeg om de compiler warnings weg te krijgen.

Je kunt die warnings wel negeren, maar dat is meestal niet zo een goed idee. Dan vallen andere warnings die misschien wel belangrijk zijn minder op.

En dan grafische displays.

Het is meestal geen goed idee om een getal eerst zwart te maken en daarna te overschrijven met een nieuw getal. Dat geeft meestal nogal lelijke effecten in het display. Dus je kunt beter op zoek naar een functie die ook meteen de achtergrond meeneemt.

En het valt mij telkens weer op dat er eigenlijk geen goede functies zijn om getallen op een display te zetten. Het is toch niet te veel gevraagd om bijvoorbeeld een getal van bijvoorbeeld 6 cijfers met 3 achter de komma? Maar in de praktijk bestaan zulke functies niet en moet ik ze telkens zelf weer maken.

De functie sprintf(s, "%6.3f", x); komt wel een beetje in de buurt, maar werkt ook niet fijn. In de Arduino IDE werkt die niet voor floats, en bovendien geeft die in sommige gevallen meer dan de 6 gevraagde cijfers. Niet handig. De enige oplossing is dan om maar weer zelf een conversie te schrijven.

blackdog

Golden Member

Hi deKees,

Dank je voor je uitleg betreffende de Clicks.

Wat betreft het zwart of een andere kleur maken om oude tekst te maskeren.
Deze techniek werkt in dit project goed zowel voor mijn groene selectie kaders alsook voor de Counter waarden.
Mijn gebruikte display opset is natuurlijk simpel en dan kom ik er wel mee weg. :)

Maar ik ben het er met je eens dat wat ik in de 5 jaar dat ik met microcontroler bezich ben, het altijd een probleem is geweest.
Je hebt me al meerdere keren geholpen met een soort sprintf(s, "%6.3f", x); bij verschillende projectjes.

Als ik nog tijd heb vandaag zal ik weer wat van het display laten zien.
Het is nu nog te rommelig, moet meer uitgelijnt worden en langzamaan komt de opbouw in mijn hoofd hoe ik het zo netjes mogelijk kan oplossen.

Wederom dank voor je hulp.

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
blackdog

Golden Member

Hi,

Ik ben weer een stukje verder met wat code vooral voor het display.
Ik zal mijn best moeten doen zoals ik al eerder aangaf om het schrijven naar het display zo veel mogelijk te beperken.

Het display/Library/Teensy LC comby is nu niet direct een Ferrary...

Dus wordt veel zaken die op het display verschijnen maar 1x of alleen als nodig weg geschreven.
waar het dus op neer komt is dit, verander zo min mogelijk pixels van het display in iedere loop doorgang.

Op het ogenblik ben ik bezig mijn drukknopjes en de gevolgen van het gebruik af te vangen in de code zodat het gele kader die op het display
verschuift van de eene instelling naar de andere, alleen een scherm update krijgt, als er een drukknopje gebruikt is.
Dit zelfde zal ik gaan doen met de P.I.D. waarde onder aan het scherm, ondanks dat ik deze waarden later bij noormaal gebruik niet ga weergeven.

Er moet zoveel mogelijk(binnen grensen) processortijd over blijven voor twee analoge ingangen, digitale temperatuur sensor en de P.I.D code.

En dan de waarde van de sensoren zo vaak mogelijk te kunnen updaten(2x per Seconde is voldoende) naar het scherm, zonder dat dit de P.I.D software in de weg zit.
Door zoveel mogelijk gebruik te maken van een zwarte achtergrond en het overschrijven van de oude tekst met een zo klein mogelijk zwart vlakje is het geheel flikker vrij.

Dit is een plaatje van het scherm, de data boven de blauwe balk is nu correct, de positie van de blauwe balk en de text hierin is de volgende stap
voor het netjes positioneren van de waarden.
De P.I.D waarden onderop blijven zo ver mogelijk aan de onderzijde staan, tot dat ze weg kunne.
Het zwarte vlak dat overblijftgaat de te meten sensoren waarde aangeven plus het verschil van het optimum 40 en 45°C.

Wat zou nu de beste optie voor de code code zijn, of maakt het niet uit?
Dat ik bij het code stuk kom of er een drukknopje is gebruikt en direct het scherm update voor dat stukje, of dat ik voor alle schermupdates wacht tot het einde van de loopt en dan alle scherm updates achter elkaar uitvoer.

Bij het laatste krijg ik het gevoel door de grote blokken die gelijk moeten worden uitgevoerd dat dit meer flikker zou kunen geven en meer vertraging in de loop.

Wat zijn jullie voorkeuren hierin.

Groet,
Bram

https://www.bramcam.nl/NA/DS18B20-TMP37-Kal/DS18B20-TMP37-Kal-80.png

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
blackdog

Golden Member

Hi,

Vanmiddag wat testen gedaan aan de electronica rond de LM317 om de uitgansspanning om te schakelen, de 12V naar 7,5V en de 5V naar 3.3V regelaar.

Ik had in het laatste schema een Logic Level MOSFet er in getekend omdat ik had aangenomen na een vluchtige blik op de datasheet dat dit de beste optie was.
De metingen aan de MOSFet ZVN4424A, gaf een kleine 20mv Source/Drain spanning als de 3,3V was gekozen.
Deze spanning wordt bepaald door de Rds On weerstand van deze MOSFet welke volgens de datasheet kleiner is dan 6Ω waar hij ook aan voldeed, en het was in mijn testen 4,5Ω.

Toen de tweede optie geprobeerd en dat was de Fairchild/ON Semi KSC5019
Met deze transistor en gebruik makend van een 10K basis weerstand, ging de spanningsval van iets meer dan 19mV naar 3,2mV.
In mijn schakeling is de transistor dus beter dan de Logic level MOSFet, dit natuur wel in acht nemend dat ik TO92 model behuizingen wou hebben.
Dus iedereen die zou willen gaan roepen, maar "dit type" is veel beter!!! ja dat weet ik. :+

Beide zijn mooie halfgeleiders en ik wil vooral de nadruk leggen op de KSC5019, dit is eigenlijk een power transistor in een TO92 behuizing.
Jammer genoeg weer een uitlopend model, maar ik heb er voldoende voor nog wat andere testen, waaronder audio toepassingen.

De datasheet voor de KSC5019MTA
www.bramcam.nl/NA/DS18B20-TMP37-Kal/KSC5019-D.pdf

De datasheet voor de ZVN4424A
www.bramcam.nl/NA/DS18B20-TMP37-Kal/ZVN4424A.pdf

De 10K basis weerstand voor de KSC5019 is ruim voldoende voor de 5mA waar ongeveer mee gewerkt word in mijn toepassing.
Die 10K is voldoende voor sturing van uit 3.3V of 5.0V uit een controler.
Met wat meer basissturing zoals 1mA, zakt de spanning over de transistor tot 1.2mV en bij 2mA in de basis is het nog maar 0,8mV.
Dat is allemaal ver voorbij wat ik nodig vind voor deze schakeling maar leuk om te melden wat mogelijk is met bepaalde componenten.

Het aangepast schema welke weer klikbaar is.
https://www.bramcam.nl/NA/DS18B20-TMP37-Kal/DS18B20-TMP37-Kal-100c-Klein.png

Laters weer meer!

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
EricP

mét CE

Hoe doen jullie dat met tekst die je regelmatig veranderd op het scherm?

Zonder ook maar enige ervaring te hebben met jouw opzet: heel veel hangt af van de aansturing van het display. Met bit-mapped dingen heb ik niet zoveel ervaring. Met character mapped wel. Als je bijvoorbeeld naar een 44780 kijkt, dan zijn veel mensen te lui om iets met een busy flag fatsoenlijk te implementeren en doen het op timing. Dat kan. Het zal ook vaak best werken. En het is traag als dikke str*nt door een dunne trechter.

Daarnaast moet je je wellicht afvragen hoe veel en hoe waak je wilt updaten. Is 2x per seconde genoeg? Dan mag die code al 5x zoveel tijd kosten als 10x per seconde - wat de kijker toch al niet meer kan volgen - om evenveel 'pijn' te doen.

Tenslotte doe ik graag dingen op interrupt basis. Nou schiet dat voor een dergelijk display misschien niet zo op (wellicht wat teveel parameters waardoor de hoeveelheid data die je moet queuen explodeert). Maar voor character based werkt dat prima: startpositie (dat is gewoon een start adres) & text in een queue en ergens gaat dat wel een keer naar het display toe. En ja, uiteraard kost dat ook processor tijd. Maar het is niet blocking waarbij je cycles staat te verstoken met niks doen tot je display eindelijk verder kan.
Dat kun je dan ook nog op basis van een busy-flag doen. Of je interrupts zo traag maken dat het op basis van timing altijd goed zou moeten gaan (dat werkt prima als je geen snelle updates nodig hebt en het kost minder processing dan meer interrupts en elke keer kijken 'of je al mag').

Het probleem waar iedere programmeur vroeg of laat tegenaan loopt, je dure CPU verdelen over de verschillende taken. Gates en Torvalds hadden daar ooit windows en linux voor gemaakt. :)

Nu is dit natuurlijk niet geschikt voor µC's maar ook daar zijn oplossingen voor. Zelf ben ik fan van FreeRTOS, ik raad je aan om hier niet mee te werken. Het gebruik van dergelijk os verijst best wat kennis van programmeren en je moet bekend zijn met alle ellende die erbij hoort zoals bijvoorbeeld thread safety. De reden dat ik het toch noem ondanks dat ik je aanraad het (nog) niet te gebruiken is dat er mooie oplossingen bestaan voor dit soort problemen.

Wat ik zou doen:
Je PID heeft de hoogste priortijd in je systeem. Deze moet op een vast interval werken anders gaat je PID niet goed functioneren. Ik zou een timer met interrupt gebruiken. Interrupt routines wil je kort houden, dus ik zou daar geen analoge zaken in lezen en schrijven. Hoe gebruik je dit dan? Je schrijft een flag, zie deze pseudocode

c code:





bool doPID = false;

void Timer1_ISR
{
	if(doPID == true)
	{
		//Als dit waar is hebben we de vorige cyclus de PID niet behandeld.
		//De andere code gebruikt teveel processortijd
	}
	doPID = true;
}



void main()
{
	//Hier ergens de timer instellen.
	
	while(true)
	{
		if(doPID)
		{
			float actual = analogRead();
			float next = PID.Calculate(actual);
			analogWrite(next);
			doPID = false;
		}
		else if(buttonIsPressed)
		{
			//Do something
			buttonIsPressed = false;
		}
		else if(displayHasToBeUpdated)
		{
			//Do something
			displayHasToBeUpdated = false;
		}
		
		...
	}
}


blackdog

Golden Member

Hi,

Gisteren nog twee plaatjes vergeten vn mijn test setup voor het schakelen van de Sensor voedingspanning.

Op een stukje overgebleven print heb ik de testschakeling gebouwd, de omhoogstaande 750Ω weerstand geeft al aan dat mijn inschatting voor de 3.3V stand niet geheel klopte. :+
Maar daar is de testsetup uiteindelijk ook voor, de onderste rode klem is voor eht sturen van de basis van de KSC5019.
De bovenste rode klem is de ingang van de regelaar en de middelste moet dan wel de uitgang zijn.
Hele mooie ontkoppel condensatoren voor zo'n testprint, maar dat was wat ik in een rommelbakje had liggen.
De onderste trimpot moet dus 200Ω worden om het regel bereik goed te halen, staat al in het schema als het goed is.
Sommige denken dat ik wel heel krap op de drop outvan de LM317 zit, dit i.v.m. rimpel spanning aan de ingang...
Nou die is er niet, de ingang is al schoon en de totale stroom zit onder de 10mA, zie de U1272A meter op het volgende plaatje.
https://www.bramcam.nl/NA/DS18B20-TMP37-Kal/DS18B20-TMP37-Kal-81.png

.

Sorry voor de wat wazige foto, de Delta link boven is de basis sturing, hier dus 3.3V en de basisweerstand is 10K voor de KSC5019.
De Rigol voeding staat op de spanning ingesteld die de andere LM317 levert als de oven op temperatuur is en dat is minimaal 7.5V.
De Fluke 287 geeft de basisstroom aan en deze basis stroom geeft een CE spanning van de KSC5019 die rond de 3,2mV zit, toppy dus!
De 34461A meter geeft de getrimde uitgangsspanning aan in de 3.3V stand.
De afwijkingen aan de uitgang als de ingangspanning naar 12V gaat is onintressant, want deze is kleiner dan 2mV.

De te meten sensoren hebben meestal een goede onderdrukking voor voedingspanning variaties
en de afwijingen die er hier optreden zijn te klein om fouten in de metingen te geven, zelfs al had ik de MOSFet hier gebruikt dan waren de afwijkingen nog te klein.
https://www.bramcam.nl/NA/DS18B20-TMP37-Kal/DS18B20-TMP37-Kal-82.png

hardbass en EricP
Ik ga nadenken over jullie opmerkingen en zal later nog wat schrijven over de afwegingen die ik al gemaakt heb.
Verder ga ik nog wat metingen doen aan stukjes van de loop die ik nu al heb draaien.

Zover ik weet, maar dat is alweer een tijdje geleden dat ik dit gelezen heb, verbruikt de P.I.D code maar heel weinig processor tijd.
Dus als die via een interrupt zou gaan en ik doe een beetje normaal met de hoeveelheid die ik naar het scherm schrijf per seconde dan moet het wel goed gaan.
Mijn vermoede is dat ik een "Window Time tussen de 1 en 5x per seconde nodig zal hebben voor een mooie regeling (het is een kleine oven)

Nu eerst weer een klant helpen, het houd niet op... ;)

Groet en dank voor de opmerkingen.
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
EricP

mét CE

Als je die PID regeling interrupt based aan de gang krijgt en verder geen rare dingen met interrupts doet (doorgaans zijn interrupts non-interruptable, dus als het tijd-kritisch is, dan moet je er dus wel voor zorgen dat het aan bod komt. Hoe tijd-kritisch jouw regeling is mag je zelf bepalen :) ), maakt het verder niet uit wat je met dat display doet als dat in de voorgrond draait (of uiteraard in een efficiënte interrupt handler). Als je tijdconstante van het te regelen geheel in seconden uitgedrukt wordt, dan zal de PID regeling ook niet op een paar μS hangen tenslotte.

Wat je verder nou zou kunnen overwegen (en je moet dus zelf inschatten of het voor jouw setup werkbaar is), is dat je alle variabelen op je display ergens stored en zo nu en dan een volledige update van het display doet. Risico is dat dingen gaan knipperen en misschien is het te traag. Het is wel lekker lui programmeren. Ergens wordt er 2x per sec. een flag gezet en vanuit de main wordt er dan wel ergens een display-update aangeroepen. Het enige wat je zelf moet doen is zorgen dat de betreffende variabelen actuele data bevatten. Afijn, zat mogelijkheden.

Succes met je klant. In the end, it's all about the money :)

Weet niet of ze er voor de Teensy ook zijn, ik gebruik regelmatig STM32 waar er voor een aantal displays drivers zijn waarin SPI icm DMA wordt gebruikt waarmee je de processor flink kan ontlasten.

https://os.mbed.com/users/hudakz/code/ILI9341_STM32F4/graph/

It's the rule that you live by and die for It's the one thing you can't deny Even though you don't know what the price is. It is justified.

Je hebt het al gezien natuurlijk. maar die ILI9341 vergt nogal wat processor-tijd inderdaad. 320x240 = 76800 pixels met elk 2 bytes voor de juiste kleur. En de library helpt ook niet. De voorbeeldjes maken eerste heel het scherm zwart en gaan dan nieuwe data schrijven. Dat ziet er niet uit dus dat wil je niet.

Het is dan de kunst om zo min mogelijk pixels te gaan sturen:
- Alleen data schrijven die verandert.
- Kaders zoveel mogelijk intact laten.
- Getallen eerst omzetten naar strings met de juiste lengte alvorens ze naar het display te schrijven.
- En als je al stukken 'zwart' moet maken om oude getallen weg te krijgen, dan liefst alleen het stuk binnen de kaders waar het nieuwe getal moet komen te staan.

Als je de display update uitstelt tot onderaan je code, dan is dat goed voor de logica van je applicatie. Dat geeft dan een scheiding tussen het functionele deel en de presentatie deel.

Maar dan wordt het meteen veel moeilijker om alleen die data te schrijven die echt veranderd is. Dus ik zou kiezen om het display bij te werken op het moment dat er data verandert.

DMA zou kunnen helpen, maar is wel weer een hele puzzel. Dan kun je per character een DMA opdracht geven om die letter vanuit je font tabel naar het display te sturen.

blackdog

Golden Member

Hi,

deKees
Ik had het al zo opgelost zoals jij al aangaf alleen de pixels wissen die nodig zijn met een gekleurt vlak, dat was zwart voor de waarden van jouw encoders,
maar ik heb het vlakje rood gemaakt met witte tekst, dat is ook goed leesbaar en verder is ook de grote van het vlakje goed te bepalen.

De drie encoders voor P, I en D gaan natuurlijk uit de code want die worden vast ingesteld maar voor het testen is het erg confortable om de waarden live te kuenn aanpassen.

Maar goed, dat was a lgeregeld en nu heb ik weer wat tijd om verder met de code te gaan en ik wil wat foutmeldingen uit de code hebben voor ik verder ga.

Hieronder de code die nog niet klaar is en daar weer onder de foutmeldingen van de compiler.
Er wordt aangegeven dat "Filter_TMP37" niet gedeclareed is...

c code:


C:\Users\jajamooiniet\Documents\Arduino\Teesy-LC-ILI9341-14\Teesy-LC-ILI9341-14.ino:365:3: error: 'Filter_TMP37' was not declared in this scope

   Filter_TMP37.AddSample(sample_TMP37_Celcius);                                   // Deze twee regels geven fouten

   ^

C:\Users\hupeldepup\Documents\Arduino\Teesy-LC-ILI9341-14\Teesy-LC-ILI9341-14.ino:366:3: error: 'Filter_NTC' was not declared in this scope

   Filter_NTC.AddSample(sample_NTC_Celcius);

   ^

En een tweede melding is deze:

c code:


C:\Users\bliepBlah\Documents\Arduino\Teesy-LC-ILI9341-14\Teesy-LC-ILI9341-14.ino:339:9: warning: unused variable 'Clicks1' [-Wunused-variable]

    int  Clicks1 = Rotary_SW1.Clicks();

         ^

En dat dan ook voor Clicks2 en Clicks3

Ik zal zondermeer dingen over het hoofd zien, maar ik staar me net als de vorige keer weer blind op de code....

c code:



#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <PID_v1.h>             // NOG NIET IN GEBRUIK
#include <JC_Button.h>          // https://github.com/JChristensen/JC_Button
#include <Wire.h>
#include "I2C_Rotary_003.h"     // deKees i2c encoder library
#include <ADC.h>

ADC *adc = new ADC();                                                         // ADC object voor de Teensy ADC

// Extra font voor het display
#include <Fonts/FreeSans9pt7b.h>
// *Extra font voor het display


// Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS-10, TFT_DC-9, TFT_MOSI-11, TFT_CLK-13, TFT_RST-8, TFT_MISO-12);
Adafruit_ILI9341 tft = Adafruit_ILI9341(10, 9, 11, 13, 8, 12);
// * Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS-10, TFT_DC-9, TFT_MOSI-11, TFT_CLK-13, TFT_RST-8, TFT_MISO-12);


// PID input en output pins
#define PIN_INPUT 0
#define PIN_OUTPUT 26
// * PID input en output pins


// Thermistor Eigenschappen Vishay NTCLE300E3502SB
#define RT0 5000                                                                     // Ω
#define B   3977                                                                     // K
#define VCC 2.4985                                                                   // Referentie Spanning van Maxim voltage reference IC
#define R   2368.85                                                                  // Weerstand naar de referentie spanning voor de NTC in Ohm
#define T0  (25 + 273.15)                                                            // Temperature T0 from datasheet, conversion from Celsius to kelvin fot the NTC Sensor
// * Thermistor Eigenschappen Vishay NTCLE300E3502SB


// Configuratie middeling voor de NTC ingang
template <class T>
class Filter 
{
public:
  int N = 0;                                                                         // Aantal te middelen waarde
  float *meetwaardes;                                                                // Opslag individuele meetwaarden
  float accumulator = 0;                                                             // Optelsom van alle individuele meetwaarden
  int index = 0;                                                                     // Meetwaarden teller

  Filter(const int n)
  {
    meetwaardes = new float[n];
    N = n;
    for(int i = 0; i < n; i++)
    {  
      meetwaardes[i] = 0;
    }
  }

  ~Filter()
  {
    delete[] meetwaardes;
  }

  void AddSample(float NewSample)
  {  
    accumulator -= meetwaardes[index];        
    meetwaardes[index] = NewSample;                                                  // Bewaar nieuwe meetwaarde
    accumulator += meetwaardes[index];                                               // Accumuleer nieuwste meetwaarde
    index++; 
    index %= N;                                                                      // Teller loopt van 0 tot N-1
  }

  float Average()
  {  
    return accumulator/N;                                                            // Bereken de gemmiddelde waarde
  }
};
// * Configuratie middeling voor de NTC ingang


// Button variabelen 
ToggleButton                                                                         // define the buttons
    btn1(1),                                                                         // this button's initial state is off
    btn2(2),                                                                         // this button's initial state is off
    btn3(3, true);                                                                   // this button's initial state is on
// * Button variabelen 


// Instellingen voor de oven temperatuur
//    int tp_low = 37;                                                               // Schakelpunt voor de PreHeat 40C oven temperatuur, NOG NIET IN GEBRUIK
//    int tp_high = 42;                                                              // Schakelpunt voor de PreHeat 45C oven temperatuur, NOG NIET IN GEBRUIK
//
//    int t40 = 40;                                                                  // 40C oven temperatuur, NOG NIET IN GEBRUIK
//    int t45 = 45;                                                                  // 45C oven temperatuur, NOG NIET IN GEBRUIK
//
//    int t40_corr = 0;                                                              // Correctie voor 40C oven temperatuur, NOG NIET IN GEBRUIK
//    int t45_corr = 0;                                                              // correctie voor 45C oven temperatuur, NOG NIET IN GEBRUIK
// * Instellingen voor de oven temperatuur


// Declare 3 rotary objects, all use the same I2C address, but different switch numbers
    I2C_Rotary Rotary_SW1(0xA0, 1);  // SW1
    I2C_Rotary Rotary_SW2(0xA0, 2);  // SW2
    I2C_Rotary Rotary_SW3(0xA0, 3);  // SW3
// * Declare 3 rotary objects, all use the same I2C address, but different switch numbers


int SW1_Old = 0;
int SW2_Old = 0;
int SW3_Old = 0;

byte btn1_Old = 0;
byte btn2_Old = 0;
byte btn3_Old = 0;


unsigned long start, finished, elapsed;


// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void setup() {
   Serial.begin(9600);
   
// i2c configuratie
   Wire.setClock(1200000);
   Wire.setSDA(18);
   Wire.setSCL(19);
   Wire.begin();
// * i2c configuratie

      
// Teensy SPI Settings
    SPI.begin();
    SPI.setClockDivider(SPI_CLOCK_DIV2);
// * Teensy SPI Settings


//  Initialize the button objects
    btn1.begin();
    btn2.begin();
    btn3.begin();
//  * Initialize the button objects


// set the LED pins as outputs
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
// * set the LED pins as outputs

    
// show the initial states
    digitalWrite(4, btn1.toggleState());
    digitalWrite(5, btn2.toggleState());
    digitalWrite(6, btn3.toggleState());
// * show the initial states


//  Initialize pinmode voor sensor power supply switching
    pinMode(7, OUTPUT);
    digitalWrite(7, LOW);
//  * Initialize pinmode voor sensor power supply switching


//  Initialize tft screen  
    tft.begin();
    tft.setRotation(1); // Horizontaal
    tft.fillScreen(ILI9341_BLACK);
// * Initialize tft screen  


// Lijnen en kaders die altijd op het scherm staan
     tft.drawRoundRect(168, 0, 150, 21, 4, 0x07E0);                                  // Groen kader bovenste tekst regel
     tft.fillRect(0, 98, 320, 38, 0x001F);                                           // Blauwe kader midden in beeld
     tft.fillRect(0, 23, 320, 4, ILI9341_GREEN);                                     // Dikke lijn onder bovenste tekstregel
     tft.fillRect(0, 57, 320, 4, ILI9341_GREEN);                                     // Dikke lijn onder Set temperature     
     tft.fillRect(0, 91, 320, 4, ILI9341_GREEN);                                     // Dikke lijn onder Set temperature    
     tft.drawLine(0, 132, 320, 132, ILI9341_WHITE); 
// * Lijnen en kaders die altijd op het scherm staan


// Tekst die altijd in beeld staat voor gekozen oven temperature
     tft.setFont(&FreeSans9pt7b);
     tft.setTextColor(0x03EF);  tft.setTextSize(0);

     tft.setCursor(2, 16);
     tft.println("NA-TMP-cal   V1.0");
    
     tft.setCursor(173, 16);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("Sensor Calibrator");

     tft.setTextColor(ILI9341_YELLOW);  tft.setTextSize(1);
     tft.setCursor(10, 48);
     tft.println("Set Oven Temperature:");

     tft.setCursor(216, 48);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(40);

     tft.setCursor(271, 48);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(45);

     // Set Celcius karakter op het scherm voor temp-40
     tft.fillCircle(299, 38, 2, 0xFFFF); 
     tft.setCursor(302, 48);
     tft.println("C");

     // Set Celcius karakter op het scherm voor temp-45
     tft.fillCircle(242, 38, 2, 0xFFFF); 
     tft.setCursor(245, 48);
     tft.println("C");
// * Tekst die altijd in beeld staat voor gekozen oven temperature


// Tekst die altijd in beeld staat voor gekozen Sensor voeding spanning
     tft.setTextColor(ILI9341_YELLOW);  tft.setTextSize(1);
     tft.setCursor(10, 82);
     tft.println("Set Sensor VCC:");

     tft.setCursor(219, 82);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("3.3V");

     tft.setCursor(275, 82);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("5.0V");
// * Tekst die altijd in beeld staat voor gekozen Sensor voeding spanning


// Set de tekst op beeld van de oven NTC
     tft.fillCircle(114, 113, 2, 0xFFFF);
     tft.setCursor(5, 123);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("NTC: 40,564  C");
// * Set de tekst op beeld van de oven NTC

   
// Set de tekst op beeld de oven T-SIC sensor
     tft.fillCircle(299, 113, 2, 0xFFFF);
     tft.setCursor(180, 123);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("T-SIC: 40,561  C");
// * Set de tekst op beeld de oven T-SIC sensor


// Set de tekst op beeld voor de P waarde
     tft.setCursor(0, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("P = ");
// * Set de tekst op beeld voor de P waarde


// Set de tekst op beeld voor de I waarde
     tft.setCursor(125, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("i = ");
// * Set de tekst op beeld voor de I waarde


// Set de tekst op beeld voor de D waarde
     tft.setCursor(230, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("D = ");
// * Set de tekst op beeld voor de D waarde
     
// * Tekst die altijd in beeld staat


// Rotary encoder Setup

// Set parameters for Rotary_SW1
   Rotary_SW1.m_MinValue = 0.0;
   Rotary_SW1.m_MaxValue = 500.0;
   Rotary_SW1.m_StepSize = 1.0;
   Rotary_SW1.m_Value    = 10.0;
   Rotary_SW1.SetDirection(1);
   Rotary_SW1.SetAccelleration(0);
// * Set parameters for Rotary_SW1


// Set parameters for Rotary_SW2
   Rotary_SW2.m_MinValue = 0.0;
   Rotary_SW2.m_MaxValue = 500.0;
   Rotary_SW2.m_StepSize = 1.0;
   Rotary_SW2.m_Value    = 20.0;
   Rotary_SW2.SetDirection(1);
   Rotary_SW2.SetAccelleration(0);
// * Set parameters for Rotary_SW2


// Set parameters for Rotary_SW3
   Rotary_SW3.m_MinValue = 0.0;
   Rotary_SW3.m_MaxValue = 500.0;
   Rotary_SW3.m_StepSize = 1.0;
   Rotary_SW3.m_Value    = 30.0;
   Rotary_SW3.SetDirection(1);
   Rotary_SW3.SetAccelleration(0);
// * Set parameters for Rotary_SW3

// * Rotary encoder Setup


// Configuratie van ADC_0 Teensy-LC
    adc->adc0->setReference(ADC_REFERENCE::REF_EXT);                                 // Selecteer de externe referentie ingang voor ADC_0
    adc->adc0->setAveraging(32);                                                     // Selecteer de middeling van de gebruikte ADC
    adc->adc0->setResolution(16);                                                    // Selecteerd de resolutie van de geselecteerde ADC
    adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED_16BITS);          // Selecteerd de conversie snelheid
    adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::LOW_SPEED);                      // Selecteerd de sample snelheid
    adc->adc0->recalibrate();                                                        // Kalibreeer de ADC
// *Configuratie van ADC_0 Teensy-LC



Filter<float> Filter_TMP37(128);
Filter<float> Filter_NTC(32); 

}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void loop(){

           Serial.println("Start...");
           start=millis();
   
    // read the buttons
    btn1.read();
    btn2.read();
    btn3.read();


    // if button state changed, update the LEDs
    if (btn1.changed()) digitalWrite(4, btn1.toggleState());
    if (btn2.changed()) digitalWrite(5, btn2.toggleState());
    if (btn3.changed()) digitalWrite(6, btn3.toggleState());

// Scan status of the deKees rotary encoders
   int  Clicks1 = Rotary_SW1.Clicks();
   int  Clicks2 = Rotary_SW2.Clicks();
   int  Clicks3 = Rotary_SW3.Clicks();
// * Scan status of the deKees rotary encoders


// Meet de oven temperatuur en als de oven op temperatuur is plaatst Oven Ready op het scherm

// Temperatuur van de TMP37
  float sample_TMP37_RAW = (float)analogRead(A9);
  float sample_TMP37_Celcius = sample_TMP37_RAW * (2.4985/65536 / 0.02);  
// * Temperatuur van de TMP37  


// Temperatuur van de NTC
  float sample_NTC_RAW = (float)analogRead(A8);
  float VRT = 2.4985 * sample_NTC_RAW / 65536.00; 
  float VR = VCC - VRT;
  float RT = VRT * R / VR; 
  float ln = log(RT / RT0);
  float TX = (1 / ((ln / B) + (1 / T0)));                                        
  float sample_NTC_Celcius = TX - 273.15;   
// * Temperatuur van de NTC


// Samples toevoegen aan het filter.
  Filter_TMP37.AddSample(sample_TMP37_Celcius);                                   // Deze twee regels geven fouten
  Filter_NTC.AddSample(sample_NTC_Celcius);
// * Samples toevoegen aan het filter.


// * Uitlezen resultaat filters.
  float avg_TMP37_Celcius = Filter_TMP37.Average();                               // Deze twee regels geven fouten
  float avg_NTC_Celcius = Filter_NTC.Average();
// * Uitlezen resultaat filters.


// * Meet de oven temperatuur en als de oven op temperatuur is plaatst Oven Ready op het scherm

           
// Plaatst kader om de gekozen temperatuur waarde.
     if ((btn1.toggleState()) == 0) {                                                // Controleer de Drukknop-1 status en voer actie uit, bij status "0" plaats kader om 40C waarde op het scherm
     tft.drawRoundRect(269, 31, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 45C
     tft.drawRoundRect(268, 30, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 45C
     tft.drawRoundRect(213, 31, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 40C
     tft.drawRoundRect(212, 30, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 40C
     btn1_Old = (btn1.toggleState());     
  }
     else {
     tft.drawRoundRect(213, 31, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 40C
     tft.drawRoundRect(212, 30, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 40C
     tft.drawRoundRect(269, 31, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 45C
     tft.drawRoundRect(268, 30, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 45C
//     btn1_Old = (btn1.toggleState());
  }
// * Plaatst kader om de gekozen temperatuur waarde.


// Plaatst kader om de gekozen Sensor VCC.
     if ((btn2.toggleState()) == 0) {                                                // Controleer de Drukknop-2 status en voer actie uit, bij status "0" plaats kader om 40C waarde op het scherm
     tft.drawRoundRect(269, 65, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 5.0V
     tft.drawRoundRect(268, 64, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 5.0V
     tft.drawRoundRect(213, 65, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 3.3V
     tft.drawRoundRect(212, 64, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 3.3V
     btn2_Old = btn2.toggleState();
  }
     else {
     tft.drawRoundRect(213, 65, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 3.3V
     tft.drawRoundRect(212, 64, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 3.3V
     tft.drawRoundRect(269, 65, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 5.0V
     tft.drawRoundRect(268, 64, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 5.0V
//     btn2_Old = btn2.toggleState();
  }
// * Plaatst kader om de gekozen temperatuur waarde.



// Plaats rotary encoder counter waarde op het display
     // Set de tekst op beeld voor de P waarde
     if ((Rotary_SW1.m_Value) != SW1_Old)
     {
     tft.fillRect(32, 220, 35, 18, ILI9341_RED);                                     // Overschrijft oude waarde met zwart blokje
     tft.setCursor(34, 234);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(Rotary_SW1.m_Value, 0);                                             // plaats "P" waarde van rotary encoder-1 op het scherm
     SW1_Old = (Rotary_SW1.m_Value);
     }

     // Set de tekst op beeld voor de I waarde
     if ((Rotary_SW2.m_Value) != SW2_Old)
     {
     tft.fillRect(148, 220, 35, 18, ILI9341_RED);                                    // Overschrijft oude waarde met zwart blokje
     tft.setCursor(150, 234);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(Rotary_SW2.m_Value, 0);                                             // plaats "I" waarde van rotary encoder-2 op het scherm
     SW2_Old = (Rotary_SW2.m_Value);
     }
     
     // Set de tekst op beeld voor de D waarde
     if ((Rotary_SW3.m_Value) != SW3_Old)
     {
     tft.fillRect(263, 220, 35, 18, ILI9341_RED);                                    // Overschrijft oude waarde met zwart blokje     
     tft.setCursor(265, 234);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(Rotary_SW3.m_Value, 0);                                             // plaats "D" waarde van rotary encoder-2 op het scherm
     SW3_Old = (Rotary_SW3.m_Value);
     }
// * Plaats rotary encoder counter waarde op het display




//  tijdelijke debug serial commands
//    Serial.print("Drukknop-1   ");  Serial.println(btn1.toggleState());
//    Serial.print("Drukknop-2   ");  Serial.println(btn2.toggleState());
//    Serial.println();
//
//    if ((btn1_Old != btn1.changed()) || (btn2_Old != btn2.changed()))
//    {
//    Serial.print("Er is een verandering");
//    }

    
// * tijdelijke debug serial commands

//          finished=millis();
//          Serial.println("Finished");
//          elapsed=finished-start;
//          Serial.print(elapsed);
//          Serial.println(" milliseconds elapsed");
//          Serial.println();
}

Ik hoop dat jullie mij hiermee kunnen helpen, ik zit nu al tegen de bijna 500 regels code aan.
Voor mijn overzicht heb ik het al omkaardert zodat het voor mij wat duidelijker is en/of terug te vinden, dit kan nog beter, maar eerst maar de foutjes er uit halen.

Dank vast en gegroet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

code:


Filter<float> Filter_TMP37(128);
Filter<float> Filter_NTC(32); 

Dus Filter_TMP37 en Filter_NTC zijn wel degelijk gedefinieerd.
Maar die staan binnen de haakjes van setup() en dus zijn ze weer weg zodra setup() klaar is.

Die moet je dus een paar regels verder naar onderen verplaatsen, voorbij het sluithaakje.

Clicks1, Clicks2 en Clicks3 worden inderdaad niet gebruikt, dus daar heeft de compiler wel gelijk. Kun je oplossen door die variabelen weg te laten:

Dus:

code:


   Rotary_SW1.Clicks();
   Rotary_SW2.Clicks();
   Rotary_SW3.Clicks();

in plaats van :

code:


   int  Clicks1 = Rotary_SW1.Clicks();
   int  Clicks2 = Rotary_SW2.Clicks();
   int  Clicks3 = Rotary_SW3.Clicks();

code:


template <class T>
class Filter 
{

Je gebruikt hier een template voor type T, maar het type T wordt verder binnen de template niet meer genoemd. Dan kun je beter de template regel weglaten zodat er een normale class definitie overblijft:

code:



class Filter 
{

De declaratie van de filters wordt dan ook eenvoudiger:

code:


   Filter Filter_TMP37(128);
   Filter Filter_NTC(32); 
blackdog

Golden Member

Hi deKees,

Je opmerkingen werken, de error zijn weg... :)

Maar nog even dit, deze regels heb ik ook zoals jij aangaf aangepast, maar moeten dat geen float zijn, of handeld de class filter dit af?

c code:


Filter<float> Filter_TMP37(128);
Filter<float> Filter_NTC(32); 

c code:



#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <PID_v1.h>             // NOG NIET IN GEBRUIK
#include <JC_Button.h>          // https://github.com/JChristensen/JC_Button
#include <Wire.h>
#include "I2C_Rotary_003.h"     // deKees i2c encoder library
#include <ADC.h>

ADC *adc = new ADC();                                                         // ADC object voor de Teensy ADC

// Extra font voor het display
#include <Fonts/FreeSans9pt7b.h>
// *Extra font voor het display


// Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS-10, TFT_DC-9, TFT_MOSI-11, TFT_CLK-13, TFT_RST-8, TFT_MISO-12);
Adafruit_ILI9341 tft = Adafruit_ILI9341(10, 9, 11, 13, 8, 12);
// * Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS-10, TFT_DC-9, TFT_MOSI-11, TFT_CLK-13, TFT_RST-8, TFT_MISO-12);


// PID input en output pins
#define PIN_INPUT 0
#define PIN_OUTPUT 26
// * PID input en output pins


// Thermistor Eigenschappen Vishay NTCLE300E3502SB
#define RT0 5000                                                                     // Ω
#define B   3977                                                                     // K
#define VCC 2.4985                                                                   // Referentie Spanning van Maxim voltage reference IC
#define R   2368.85                                                                  // Weerstand naar de referentie spanning voor de NTC in Ohm
#define T0  (25 + 273.15)                                                            // Temperature T0 from datasheet, conversion from Celsius to kelvin fot the NTC Sensor
// * Thermistor Eigenschappen Vishay NTCLE300E3502SB


// Configuratie middeling voor de NTC ingang
class Filter 
{
public:
  int N = 0;                                                                         // Aantal te middelen waarde
  float *meetwaardes;                                                                // Opslag individuele meetwaarden
  float accumulator = 0;                                                             // Optelsom van alle individuele meetwaarden
  int index = 0;                                                                     // Meetwaarden teller

  Filter(const int n)
  {
    meetwaardes = new float[n];
    N = n;
    for(int i = 0; i < n; i++)
    {  
      meetwaardes[i] = 0;
    }
  }

  ~Filter()
  {
    delete[] meetwaardes;
  }

  void AddSample(float NewSample)
  {  
    accumulator -= meetwaardes[index];        
    meetwaardes[index] = NewSample;                                                  // Bewaar nieuwe meetwaarde
    accumulator += meetwaardes[index];                                               // Accumuleer nieuwste meetwaarde
    index++; 
    index %= N;                                                                      // Teller loopt van 0 tot N-1
  }

  float Average()
  {  
    return accumulator/N;                                                            // Bereken de gemmiddelde waarde
  }
};
// * Configuratie middeling voor de NTC ingang


// Button variabelen 
ToggleButton                                                                         // define the buttons
    btn1(1),                                                                         // this button's initial state is off
    btn2(2),                                                                         // this button's initial state is off
    btn3(3, true);                                                                   // this button's initial state is on
// * Button variabelen 


// Instellingen voor de oven temperatuur
//    int tp_low = 37;                                                               // Schakelpunt voor de PreHeat 40C oven temperatuur, NOG NIET IN GEBRUIK
//    int tp_high = 42;                                                              // Schakelpunt voor de PreHeat 45C oven temperatuur, NOG NIET IN GEBRUIK
//
//    int t40 = 40;                                                                  // 40C oven temperatuur, NOG NIET IN GEBRUIK
//    int t45 = 45;                                                                  // 45C oven temperatuur, NOG NIET IN GEBRUIK
//
//    int t40_corr = 0;                                                              // Correctie voor 40C oven temperatuur, NOG NIET IN GEBRUIK
//    int t45_corr = 0;                                                              // correctie voor 45C oven temperatuur, NOG NIET IN GEBRUIK
// * Instellingen voor de oven temperatuur


// Declare 3 rotary objects, all use the same I2C address, but different switch numbers
    I2C_Rotary Rotary_SW1(0xA0, 1);  // SW1
    I2C_Rotary Rotary_SW2(0xA0, 2);  // SW2
    I2C_Rotary Rotary_SW3(0xA0, 3);  // SW3
// * Declare 3 rotary objects, all use the same I2C address, but different switch numbers


int SW1_Old = 0;
int SW2_Old = 0;
int SW3_Old = 0;

byte btn1_Old = 0;
byte btn2_Old = 0;
byte btn3_Old = 0;


unsigned long start, finished, elapsed;


Filter Filter_TMP37(128);
Filter Filter_NTC(32); 










// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void setup() {
   Serial.begin(9600);
   
// i2c configuratie
   Wire.setClock(1200000);
   Wire.setSDA(18);
   Wire.setSCL(19);
   Wire.begin();
// * i2c configuratie

      
// Teensy SPI Settings
    SPI.begin();
    SPI.setClockDivider(SPI_CLOCK_DIV2);
// * Teensy SPI Settings


//  Initialize the button objects
    btn1.begin();
    btn2.begin();
    btn3.begin();
//  * Initialize the button objects


// set the LED pins as outputs
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
// * set the LED pins as outputs

    
// show the initial states
    digitalWrite(4, btn1.toggleState());
    digitalWrite(5, btn2.toggleState());
    digitalWrite(6, btn3.toggleState());
// * show the initial states


//  Initialize pinmode voor sensor power supply switching
    pinMode(7, OUTPUT);
    digitalWrite(7, LOW);
//  * Initialize pinmode voor sensor power supply switching


//  Initialize tft screen  
    tft.begin();
    tft.setRotation(1); // Horizontaal
    tft.fillScreen(ILI9341_BLACK);
// * Initialize tft screen  


// Lijnen en kaders die altijd op het scherm staan
     tft.drawRoundRect(168, 0, 150, 21, 4, 0x07E0);                                  // Groen kader bovenste tekst regel
     tft.fillRect(0, 98, 320, 38, 0x001F);                                           // Blauwe kader midden in beeld
     tft.fillRect(0, 23, 320, 4, ILI9341_GREEN);                                     // Dikke lijn onder bovenste tekstregel
     tft.fillRect(0, 57, 320, 4, ILI9341_GREEN);                                     // Dikke lijn onder Set temperature     
     tft.fillRect(0, 91, 320, 4, ILI9341_GREEN);                                     // Dikke lijn onder Set temperature    
     tft.drawLine(0, 132, 320, 132, ILI9341_WHITE); 
// * Lijnen en kaders die altijd op het scherm staan


// Tekst die altijd in beeld staat voor gekozen oven temperature
     tft.setFont(&FreeSans9pt7b);
     tft.setTextColor(0x03EF);  tft.setTextSize(0);

     tft.setCursor(2, 16);
     tft.println("NA-TMP-cal   V1.0");
    
     tft.setCursor(173, 16);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("Sensor Calibrator");

     tft.setTextColor(ILI9341_YELLOW);  tft.setTextSize(1);
     tft.setCursor(10, 48);
     tft.println("Set Oven Temperature:");

     tft.setCursor(216, 48);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(40);

     tft.setCursor(271, 48);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(45);

     // Set Celcius karakter op het scherm voor temp-40
     tft.fillCircle(299, 38, 2, 0xFFFF); 
     tft.setCursor(302, 48);
     tft.println("C");

     // Set Celcius karakter op het scherm voor temp-45
     tft.fillCircle(242, 38, 2, 0xFFFF); 
     tft.setCursor(245, 48);
     tft.println("C");
// * Tekst die altijd in beeld staat voor gekozen oven temperature


// Tekst die altijd in beeld staat voor gekozen Sensor voeding spanning
     tft.setTextColor(ILI9341_YELLOW);  tft.setTextSize(1);
     tft.setCursor(10, 82);
     tft.println("Set Sensor VCC:");

     tft.setCursor(219, 82);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("3.3V");

     tft.setCursor(275, 82);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("5.0V");
// * Tekst die altijd in beeld staat voor gekozen Sensor voeding spanning


// Set de tekst op beeld van de oven NTC
     tft.fillCircle(114, 113, 2, 0xFFFF);
     tft.setCursor(5, 123);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("NTC: 40,564  C");
// * Set de tekst op beeld van de oven NTC

   
// Set de tekst op beeld de oven T-SIC sensor
     tft.fillCircle(299, 113, 2, 0xFFFF);
     tft.setCursor(180, 123);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("T-SIC: 40,561  C");
// * Set de tekst op beeld de oven T-SIC sensor


// Set de tekst op beeld voor de P waarde
     tft.setCursor(0, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("P = ");
// * Set de tekst op beeld voor de P waarde


// Set de tekst op beeld voor de I waarde
     tft.setCursor(125, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("i = ");
// * Set de tekst op beeld voor de I waarde


// Set de tekst op beeld voor de D waarde
     tft.setCursor(230, 235);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println("D = ");
// * Set de tekst op beeld voor de D waarde
     
// * Tekst die altijd in beeld staat


// Rotary encoder Setup

// Set parameters for Rotary_SW1
   Rotary_SW1.m_MinValue = 0.0;
   Rotary_SW1.m_MaxValue = 500.0;
   Rotary_SW1.m_StepSize = 1.0;
   Rotary_SW1.m_Value    = 10.0;
   Rotary_SW1.SetDirection(1);
   Rotary_SW1.SetAccelleration(0);
// * Set parameters for Rotary_SW1


// Set parameters for Rotary_SW2
   Rotary_SW2.m_MinValue = 0.0;
   Rotary_SW2.m_MaxValue = 500.0;
   Rotary_SW2.m_StepSize = 1.0;
   Rotary_SW2.m_Value    = 20.0;
   Rotary_SW2.SetDirection(1);
   Rotary_SW2.SetAccelleration(0);
// * Set parameters for Rotary_SW2


// Set parameters for Rotary_SW3
   Rotary_SW3.m_MinValue = 0.0;
   Rotary_SW3.m_MaxValue = 500.0;
   Rotary_SW3.m_StepSize = 1.0;
   Rotary_SW3.m_Value    = 30.0;
   Rotary_SW3.SetDirection(1);
   Rotary_SW3.SetAccelleration(0);
// * Set parameters for Rotary_SW3

// * Rotary encoder Setup


// Configuratie van ADC_0 Teensy-LC
    adc->adc0->setReference(ADC_REFERENCE::REF_EXT);                                 // Selecteer de externe referentie ingang voor ADC_0
    adc->adc0->setAveraging(32);                                                     // Selecteer de middeling van de gebruikte ADC
    adc->adc0->setResolution(16);                                                    // Selecteerd de resolutie van de geselecteerde ADC
    adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED_16BITS);          // Selecteerd de conversie snelheid
    adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::LOW_SPEED);                      // Selecteerd de sample snelheid
    adc->adc0->recalibrate();                                                        // Kalibreeer de ADC
// *Configuratie van ADC_0 Teensy-LC

}










// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void loop(){

           Serial.println("Start...");
           start=millis();
   
// read the buttons
    btn1.read();
    btn2.read();
    btn3.read();
// * read the buttons


// if button state changed, update the LEDs
    if (btn1.changed()) digitalWrite(4, btn1.toggleState());
    if (btn2.changed()) digitalWrite(5, btn2.toggleState());
    if (btn3.changed()) digitalWrite(6, btn3.toggleState());
// * if button state changed, update the LEDs


// Scan status of the deKees rotary encoders
   Rotary_SW1.Clicks();
   Rotary_SW2.Clicks();
   Rotary_SW3.Clicks();
// * Scan status of the deKees rotary encoders


// Meet de oven temperatuur en als de oven op temperatuur is plaatst Oven Ready op het scherm

// Temperatuur van de TMP37
  float sample_TMP37_RAW = (float)analogRead(A9);
  float sample_TMP37_Celcius = sample_TMP37_RAW * (2.4985/65536 / 0.02);  
// * Temperatuur van de TMP37  


// Temperatuur van de NTC
  float sample_NTC_RAW = (float)analogRead(A8);
  float VRT = 2.4985 * sample_NTC_RAW / 65536.00; 
  float VR = VCC - VRT;
  float RT = VRT * R / VR; 
  float ln = log(RT / RT0);
  float TX = (1 / ((ln / B) + (1 / T0)));                                        
  float sample_NTC_Celcius = TX - 273.15;   
// * Temperatuur van de NTC


// Samples toevoegen aan het filter.
  Filter_TMP37.AddSample(sample_TMP37_Celcius);                                   // Deze twee regels geven fouten
  Filter_NTC.AddSample(sample_NTC_Celcius);
// * Samples toevoegen aan het filter.


// * Uitlezen resultaat filters.
  float avg_TMP37_Celcius = Filter_TMP37.Average();                               // Deze twee regels geven fouten
  float avg_NTC_Celcius = Filter_NTC.Average();
// * Uitlezen resultaat filters.


// * Meet de oven temperatuur en als de oven op temperatuur is plaatst Oven Ready op het scherm

           
// Plaatst kader om de gekozen temperatuur waarde.
     if ((btn1.toggleState()) == 0) {                                                // Controleer de Drukknop-1 status en voer actie uit, bij status "0" plaats kader om 40C waarde op het scherm
     tft.drawRoundRect(269, 31, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 45C
     tft.drawRoundRect(268, 30, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 45C
     tft.drawRoundRect(213, 31, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 40C
     tft.drawRoundRect(212, 30, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 40C
     btn1_Old = (btn1.toggleState());     
  }
     else {
     tft.drawRoundRect(213, 31, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 40C
     tft.drawRoundRect(212, 30, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 40C
     tft.drawRoundRect(269, 31, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 45C
     tft.drawRoundRect(268, 30, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 45C
//     btn1_Old = (btn1.toggleState());
  }
// * Plaatst kader om de gekozen temperatuur waarde.


// Plaatst kader om de gekozen Sensor VCC.
     if ((btn2.toggleState()) == 0) {                                                // Controleer de Drukknop-2 status en voer actie uit, bij status "0" plaats kader om 40C waarde op het scherm
     tft.drawRoundRect(269, 65, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 5.0V
     tft.drawRoundRect(268, 64, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 5.0V
     tft.drawRoundRect(213, 65, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 3.3V
     tft.drawRoundRect(212, 64, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 3.3V
     btn2_Old = btn2.toggleState();
  }
     else {
     tft.drawRoundRect(213, 65, 49, 22, 3, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 3.3V
     tft.drawRoundRect(212, 64, 51, 24, 4, ILI9341_BLACK);                           // Overschrijft groene kader met zwart van 3.3V
     tft.drawRoundRect(269, 65, 49, 22, 3, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 5.0V
     tft.drawRoundRect(268, 64, 51, 24, 4, ILI9341_YELLOW);                          // Plaatst groene kader om de waarde 5.0V
//     btn2_Old = btn2.toggleState();
}
// * Plaatst kader om de gekozen temperatuur waarde.



// Plaats rotary encoder counter waarde op het display
     // Set de tekst op beeld voor de P waarde
     if ((Rotary_SW1.m_Value) != SW1_Old)
     {
     tft.fillRect(32, 220, 35, 18, ILI9341_RED);                                     // Overschrijft oude waarde met zwart blokje
     tft.setCursor(34, 234);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(Rotary_SW1.m_Value, 0);                                             // plaats "P" waarde van rotary encoder-1 op het scherm
     SW1_Old = (Rotary_SW1.m_Value);
     }

     // Set de tekst op beeld voor de I waarde
     if ((Rotary_SW2.m_Value) != SW2_Old)
     {
     tft.fillRect(148, 220, 35, 18, ILI9341_RED);                                    // Overschrijft oude waarde met zwart blokje
     tft.setCursor(150, 234);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(Rotary_SW2.m_Value, 0);                                             // plaats "I" waarde van rotary encoder-2 op het scherm
     SW2_Old = (Rotary_SW2.m_Value);
     }
     
     // Set de tekst op beeld voor de D waarde
     if ((Rotary_SW3.m_Value) != SW3_Old)
     {
     tft.fillRect(263, 220, 35, 18, ILI9341_RED);                                    // Overschrijft oude waarde met zwart blokje     
     tft.setCursor(265, 234);
     tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
     tft.println(Rotary_SW3.m_Value, 0);                                             // plaats "D" waarde van rotary encoder-2 op het scherm
     SW3_Old = (Rotary_SW3.m_Value);
     }
// * Plaats rotary encoder counter waarde op het display




//  tijdelijke debug serial commands
//    Serial.print("Drukknop-1   ");  Serial.println(btn1.toggleState());
//    Serial.print("Drukknop-2   ");  Serial.println(btn2.toggleState());
//    Serial.println();
//
//    if ((btn1_Old != btn1.changed()) || (btn2_Old != btn2.changed()))
//    {
//    Serial.print("Er is een verandering");
//    }

    
// * tijdelijke debug serial commands

//          finished=millis();
          Serial.println(avg_TMP37_Celcius);
//          elapsed=finished-start;
//          Serial.print(elapsed);
          Serial.println(avg_NTC_Celcius);
//          Serial.println();
}

Dank,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

Het filter gebruikt al floats voor de samples en de meetwaarden. Dat zit al zo in de class ingebouwd. In de oorspronkelijke versie was dat nog een type 'T' zodat je kon switchen tussen int en float om het verschil te zien, maar in de laatste versie is daar niks meer van over.

De getallen 128 en 32 zijn wel integers. Die worden gebruikt om te kiezen hoeveel samples je meeneemt in het filter. Dat kunnen dus gewoon integers blijven.