Arduino Frequentie generator en pulsbreedte

Ja, dat kan. Maar dan wordt het al snel onoverzichtelijk, en je maakt gemakkelijk foutjes. Dan is het beter om de variabelen te bundelen in een class. En dan zou ik alle logica ook binnen die class bouwen.
Met zo een class kun je zoveel strings maken als je analoge poorten hebt.

Dat zou dan zo kunnen werken:

code:



class ANALOG_BUTTON
{
public:
   void setup(int PinNr)
   {  m_PinNr = PinNr;
   }

   bool check(int &Action)
   { 
      if(m_Timer != millis())
      {  m_Timer = millis();
      
         int NewValue = analogRead(m_PinNr);
         if(m_Counter < 0)
         {  if(near(NewValue,0))
            m_Counter += 1;
         }
         else
         {  if( near(NewValue, m_LastValue) )
            {  const int MaxDebounce = 50; 
               if( m_Counter < MaxDebounce)
               {  // Same value multiple times in a row
                  m_Counter += 1;
               }   
               else
               {  Action = decodeButton(m_LastValue);
                  if(Action != 0)
                  {  m_Counter = -50;
                     return true;
                  }
               }
            }
            else
            {  // Value has changed. Register new value and restart counter.
               m_LastValue = NewValue;
               m_Counter = 0;
            }
         }
      }
      return false;
   }

   bool near(int x1, int x2)
   {  int Margin = 20;
      return ((x1 > (x2 - Margin)) && (x1 < (x2 + Margin)) );  
   }

   int decodeButton(int AnalogValue)
   {  // - Assuming a resistor ladder of 9 equal resistors.  
      static const int Table[] = 
      {  1024 * 0 / 9, 
         1024 * 1 / 9, 
         1024 * 2 / 9, 
         1024 * 3 / 9, 
         1024 * 4 / 9, 
         1024 * 5 / 9, 
         1024 * 6 / 9, 
         1024 * 7 / 9, 
         1024 * 8 / 9, 
         1024 * 9 / 9, 
      };
      
      for(int i = 0; ; i++)
      {  if(i >= 10)
         {  return 0;
         }
         if(near(AnalogValue, Table[i]))
         {  return i;
         }
      }
   }

   int           m_PinNr;
   unsigned long m_Timer;
   int           m_LastValue;
   int           m_Counter;
};


ANALOG_BUTTON Button1;
ANALOG_BUTTON Button2;
ANALOG_BUTTON Button3;

void setup()
{
   Serial.begin(9600);
   
   Button1.setup(A1);  // Button1 uses analog pin A1
   Button2.setup(A2);  // Button2 uses analog pin A2
   Button3.setup(A3);  // Button3 uses analog pin A3
}

void loop() 
{
   int Action;
   if(Button1.check(Action))
   {  Serial.print("- Button 1, Action "); Serial.println(Action);
   
      if(Action == 1)
      {  // Code voor Button1 Action 1
      }
      if(Action == 2)
      {  // Code voor Button1 Action 2
      }
   }

   if(Button2.check(Action))
   {  Serial.print("- Button 2, Action "); Serial.println(Action);

      if(Action == 1)
      {  // Code voor Button2 Action 1
      }
      if(Action == 2)
      {  // Code voor Button2 Action 2
      }
   }

   if(Button3.check(Action))
   {  Serial.print("- Button 3, Action "); Serial.println(Action);

      if(Action == 1)
      {  // Code voor Button3 Action 1
      }
      if(Action == 2)
      {  // Code voor Button3 Action 2
      }
   }
}

[Bericht gewijzigd door deKees op dinsdag 17 december 2019 01:25:35 (84%)

blackdog

Golden Member

Hi deKees,

Ik heb vanochtend en vanavond het laatste stukje code doorgenomen en ik doorzie het niet goed of jij hebt mijn uitleg niet begrepen.
Laten we er vanuitgaan dat jij mij wel begrijpt en dat ik codeblind ben *grin*

Mooi, nogmaals mijn uitgangspunt, drie annaloge ingangen waar een x aantal drukknopjes aanhangen b.v. jouw voorstel van 9 gelijke weerstanden.
Deze drie groepjes werken geheel afzonderlijk, dus als ik van de eerste groep schakelaar-3 indruk dan wordt de taak die aan die knop hangt ge-latcht en uitgevoerd.
Deze actie beinvloed niet de toestand van een of beide andere twee groepjes.
De hoeveelheid schakelaars kan varieren, bij drie schakelaars in groep-a kan de rest van de weerstandswaarde van de deler
vervangen worden door een weerstand van de vervangende waarde.

Zoals de code er uitziet, de je als laatste van gisterenavond, kan ik dit gedrag niet herkennen zoals hier omschreven.
Nogmaals, dit is alleen voor later, niet voor dit meetinstrumentje, het is makkelijk dat ik wat code heb voor andere meetinstrumenten zodat ik microcontrolers wat vaker ga gebruiken voor bestuur functies.
Duuw er dus niet te veel tijd in..
Natuurlijk word je hulp zeer gewardeerd!

Groet,
Bram

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

Toch wel, hoe zal ik het uitleggen.

Het begint met een 'class' definitie. Daarmee kun je een nieuw soort variabele definiëren. Die klasse heet ANALOG_BUTTON.

code:


class ANALOG_BUTTON
{
   ...

   int           m_PinNr;
   unsigned long m_Timer;
   int           m_LastValue;
   int           m_Counter;   
};

Binnen de class wordt een viertal variabelen gedefinieerd. Elke variabele die met die class wordt aangemaakt krijgt een eigen set van die 4 variabelen.

Even later worden er 3 variabelen van dat type aangemaakt.

code:


ANALOG_BUTTON Button1;
ANALOG_BUTTON Button2;
ANALOG_BUTTON Button3;

Elk van die 3 variabelen hebben hun eigen kopie van de getallen die in de class zijn gedefiniëerd. Die Button1, Button2 en Button3 hebben elk hun eigen m_PinNr, m_Counter enz.
Je kunt hier nog meer ANALOG_BUTTON's toevoegen, zoveel je wilt.

In de arduino setup() worden er dan analog pin nummers gekoppeld. Elke ANALOG_BUTTON krijgt zijn eigen pin nr.

code:


void setup()
{
   Serial.begin(9600);
   
   Button1.setup(A1);  // Button1 uses analog pin A1
   Button2.setup(A2);  // Button2 uses analog pin A2
   Button3.setup(A3);  // Button3 uses analog pin A3
}

Vervolgens kun je dan in de loop() controleren or er een switch aktief is. Daarbij reageert Button1 op switches die zijn gekoppeld aan A1, omdat die in Button1.Setup(A1) aan elkaar gekoppeld zijn. Zo reageert Button2 op A2, en Button3 op A3.

Het testen van de switches doe je door de check() funktie aan te roepen, ook weer gekoppeld aan één van de Button variabelen.

code:


void loop()
{  
   int Action;
   
   if(Button1.check(Action))
   {  // Switch op A1 is ingedrukt.
   }
   else
   {  // Geen switch op A1 aktief.
   }
}

De check() funktie van Button1 gebruikt de variabelen van Button1. Die leest de analoge waarde van A1, en berekent of er een switch aktief is.

Zolang er geen switch gesloten is, geeft check false terug en gaat het verder in de else.

Is er wel een switch gesloten, dan berekent check() welke dat is en zet een getal in de Action variabele. En bovendien wordt er dan een true teruggegeven, zodat het programma nu wel het if() gedeelte induikt. Daar kun je dus testen welke switch is ingedrukt, en de bijbehorende aktie uitvoeren.

Ditzelfde kun je dan ook doen met de andere Button variabele.

blackdog

Golden Member

Hi deKees,

Dank voor de extra uitleg, maar...
Het kwartje valt nog niet.

Het kost veel inzet het te doorgronden door mijn probleem met taal.

Ik zie te veel Button in de code staan :-)
Is er een mogelijkheid om een roep b.v. die allen aan zeg A1 hangen te voorzien van zoiets als Groep_a1.
Zodat ik het onderscheid ga zien tussen groep functies en de variabelen die voor de echte drukknoppen worden gebruikt,
ik hoop dat je begrijpt wat ik bedoel.

Ik denk dat ik wel begrijp dat je een deel van de code steeds opnieuw gebruikt onafhankelijk van of ik nu twee annaloge ingangen gebruik, of zes stuks.

Ben wezen zoeken naar een goede uitleg van Classes, de meeste uitleg gaan direct veel te diep, starten niet met de LED knipper modus :-)
Jip en Janne begin dus, maar ben nu al te moe om het verder uit te zoeken en te begrijpen, morgen heb ik weer wat tijd hier voor.

Als laatste dacht ik laat ik eens iets ombouwen van jouw code om het duidelijk te maken wat ik bedoel, en dat doe ik met de code uit de loop.
Geen idee of dit kan of klopt maar om duidelijk te maken wat ik bedoel.

c code:


void loop() 
{
   int Action;
   if(Button1.check(Action))
   {  Serial.print("- Groep-A0, Action "); Serial.println(Action);
   
      if(Action == 1)
      {  // Code voor Groep-A0 Knop_1
      }
      if(Action == 2)
      {  // Code voor Groep-A0 Knop_2
      }
   }

   if(Button2.check(Action))
   {  Serial.print("- Groep-A1, Action "); Serial.println(Action);

      if(Action == 1)
      {  // Code voor Groep-A1 Knop_1
      }
      if(Action == 2)
      {  // Code voor Groep-A1 Knop_2
      }
   }

   if(Button3.check(Action))
   {  Serial.print("- Groep-A2, Action "); Serial.println(Action);

      if(Action == 1)
      {  // Code voor Groep-A2 Knop_1
      }
      if(Action == 2)
      {  // Code voor Groep-A2 Knop_2
      }
   }
}

Dit is voor jou misschien van weinig betekenins maar voor mij erg belangrijk om de code te doorzien.
De opmerking over de haakjes die niet goed staan in mijn code begrijp ik natuurlijk, dat is de norm,
maar voor mijn brein is die haakjes positie heel rommelig en raak daardoor snel de weg kwijt. :-)
Iedereen zijn eigen mix van abberaties...

Dank en groet,
Bram

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

Ja dat kan zo. Het stukje onder de if is de applikatie waar de switches gekoppeld worden aan de gewenste akties.

Als je het eens opbouwt dan kun je in de arduino monitor zien wat er gebeurt.

En als er teveel 'button' instaat dan kun je die buttons ook een andere naam geven. En ook de 'Action' variabele kun je bijv SwitchNr noemen. En de class naam kun je ook aanpassen naar bijv ANALOG_BUTTON_GROUP. Dan krijg je zoiets als dit, exact hetzelfde programma met andere namen:

code:



class ANALOG_BUTTON_GROUP
{
public:
   void setup(int PinNr)
   {  m_PinNr = PinNr;
   }

   bool check(int &Action)
   { 
      if(m_Timer != millis())
      {  m_Timer = millis();
      
         int NewValue = analogRead(m_PinNr);
         if(m_Counter < 0)
         {  if(near(NewValue,0))
            m_Counter += 1;
         }
         else
         {  if( near(NewValue, m_LastValue) )
            {  const int MaxDebounce = 50; 
               if( m_Counter < MaxDebounce)
               {  // Same value multiple times in a row
                  m_Counter += 1;
               }   
               else
               {  Action = decodeButton(m_LastValue);
                  if(Action != 0)
                  {  m_Counter = -50;
                     return true;
                  }
               }
            }
            else
            {  // Value has changed. Register new value and restart counter.
               m_LastValue = NewValue;
               m_Counter = 0;
            }
         }
      }
      return false;
   }

   bool near(int x1, int x2)
   {  int Margin = 20;
      return ((x1 > (x2 - Margin)) && (x1 < (x2 + Margin)) );  
   }

   int decodeButton(int AnalogValue)
   {  // - Assuming a resistor ladder of 9 equal resistors.  
      static const int Table[] = 
      {  1024 * 0 / 9, 
         1024 * 1 / 9, 
         1024 * 2 / 9, 
         1024 * 3 / 9, 
         1024 * 4 / 9, 
         1024 * 5 / 9, 
         1024 * 6 / 9, 
         1024 * 7 / 9, 
         1024 * 8 / 9, 
         1024 * 9 / 9, 
      };
      
      for(int i = 0; ; i++)
      {  if(i >= 10)
         {  return 0;
         }
         if(near(AnalogValue, Table[i]))
         {  return i;
         }
      }
   }

   int           m_PinNr;
   unsigned long m_Timer;
   int           m_LastValue;
   int           m_Counter;
};


ANALOG_BUTTON_GROUP GroepA1;
ANALOG_BUTTON_GROUP GroepA2;
ANALOG_BUTTON_GROUP GroepA3;

void setup()
{
   Serial.begin(9600);
   
   GroepA1.setup(A1);  // GroepA1 gebruikt analog pin A1
   GroepA2.setup(A2);  // GroepA2 gebruikt analog pin A2
   GroepA3.setup(A3);  // GroepA3 gebruikt analog pin A3
}

void loop() 
{
   int SwitchNr;

   if(GroepA1.check(SwitchNr))
   {  Serial.print("- GroepA1, SwitchNr "); Serial.println(SwitchNr);
   
      if(SwitchNr == 1)
      {  // Code voor GroepA1 SwitchNr 1
      }
      if(SwitchNr == 2)
      {  // Code voor GroepA1 SwitchNr 2
      }
   }

   if(GroepA2.check(SwitchNr))
   {  Serial.print("- GroepA2, SwitchNr "); Serial.println(SwitchNr);

      if(SwitchNr == 1)
      {  // Code voor GroepA2, SwitchNr 1
      }
      if(SwitchNr == 2)
      {  // Code voor GroepA2, SwitchNr 2
      }
   }

   if(GroepA3.check(SwitchNr))
   {  Serial.print("- GroepA3, SwitchNr "); Serial.println(SwitchNr);

      if(SwitchNr == 1)
      {  // Code voor GroepA3, SwitchNr 1
      }
      if(SwitchNr == 2)
      {  // Code voor GroepA3, SwitchNr 2
      }
   }
}
blackdog

Golden Member

Hi deKees,

Vlak voor ik plat ga denk ik dat ik nu wat meer begrijp....
Hieronder mijn interpretatie van een deel van de opbouw.

class ANALOG_BUTTON_GROUP <= dit is de naam van jouw stukje code dat een class is

Hieronder wordt aangegeven dat deze code drie groepjes bevat en wel GroepA1, GroepA2 en GroepA3
ANALOG_BUTTON_GROUP GroepA1;
ANALOG_BUTTON_GROUP GroepA2;
ANALOG_BUTTON_GROUP GroepA3;

En hier wort aangegeven welke analoge ingangen doorde drie groepen gebruikt wordt.
GroepA1.setup(A1); // GroepA1 gebruikt analog pin A1
GroepA2.setup(A2); // GroepA2 gebruikt analog pin A2
GroepA3.setup(A3); // GroepA3 gebruikt analog pin A3

Van het volgende stukje snap ik tot nogtoe helemaal niets...
void setup(int PinNr)
{ m_PinNr = PinNr;
}

bool check(int &Action)
{
if(m_Timer != millis())
{ m_Timer = millis();

int NewValue = analogRead(m_PinNr);

En dan heb ik het over: m_PinNr = PinNr, hoe zit dit gekoppeld aan A1, A2 of A3 in de code?
Ik neem aan dit dat stukje code de desbetreffende analoge ingang uitleest, of zie ik dit verkeerd?

Morgen weer een dag!

Groet,
Bram

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

Interpretatie klopt helemaal.

code:


void setup(int PinNr)
{ m_PinNr = PinNr;
}

Dit is de definitie van een setup funktie (subroutine). Die funktie is een onderdeel van de class definitie. De funktie heeft een parameter (PinNr) die je meegeeft als je de funktie aanroept. Het enige wat de funktie hier doet is die parameter kopiëren naar de class variabele m_PinNr. Daarmee wordt de PinNr binnen de class opgeslagen.

Als je de funktie wilt uitvoeren dan moet je die koppelen aan een class variabele. Door die koppeling krijgt de funktie toegang tot de data binnen de class.

Dat doe je met :

code:


  GroepA1.setup(A1);

Hier gebruik je de setup() funktie. PinNr wordt gelijk aan A1 en wordt opgeslagen in de m_PinNr variabele van GroepA1.

Later wordt die variabele gebruikt door de check() funktie. Die doet:

code:


int NewValue = analogRead(m_PinNr);

Die doet analogRead met het PinNr uit m_PinNr. Voor GroepA1 is dat A1, voor GroepA2 is dat A2, omdat die getallen door setup() zijn vastgelegd.

Ook die check() funktie moet aan een class variabele gekoppeld worden als je hem gebruikt. Dus:

code:


   GroepA1.check( .. ); 
blackdog

Golden Member

Hi deKees,

Vanavond de weerstands string uitgebreid naar de negen stuks 1K en de analoge ingangen aangepast in de code naar de annaloge ingangsnummers die ik gebruikte.

Werkt! :D

Dank en groet.
Bram

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

Golden Member

Hi deKees, :-)

Ik heb de code nog een beetje aangepast wat het uitvoerende deel betreft en nog wat extra info er bij gezet.
Wil jij als je tijd hebt er een blik op werpen en aanpassen waar nodig.

Pas aan of gooi er uit wat bij de omschijving staat een het begin van de code, het is van jou, jij bepaald dat ;-)

c code:


/*  Multi group Analog button selector
 * 
 * Created      : December, 2019
 * By           : CJ van der Hoeven
 *
 * Purpose      : Reading out multiple switches on a single analog input of an Arduino Microcontroler (here as an example: 9x a switch per analog input in three groups)
 *              
 *              
 * Featuring    : Multiple customizable to more or less groups and also more or less switches per group 
 *                
 * The code has been adapted for my application.      
 * Blackdog, www.circuitsonline.net Netherlands
 * 
 * The code is owned by: CJ van der Hoeven
 *                
 */


class ANALOG_BUTTON_GROUP
{
public:
   void setup(int PinNr)
   {  m_PinNr = PinNr;
   }

   bool check(int &Action)
   { 
      if(m_Timer != millis())
      {  m_Timer = millis();
      
         int NewValue = analogRead(m_PinNr);
         if(m_Counter < 0)
         {  if(near(NewValue,0))
            m_Counter += 1;
         }
         else
         {  if( near(NewValue, m_LastValue) )
            {  const int MaxDebounce = 50; 
               if( m_Counter < MaxDebounce)
               {  // Same value multiple times in a row
                  m_Counter += 1;
               }   
               else
               {  Action = decodeButton(m_LastValue);
                  if(Action != 0)
                  {  m_Counter = -50;
                     return true;
                  }
               }
            }
            else
            {  // Value has changed. Register new value and restart counter.
               m_LastValue = NewValue;
               m_Counter = 0;
            }
         }
      }
      return false;
   }

   bool near(int x1, int x2)
   {  int Margin = 20;                          // this helps with the precision of the resistor divider and the inaccuracy of the ADC, the measured value of a switch can be between +20 and -20 LSB of the ADC.
      return ((x1 > (x2 - Margin)) && (x1 < (x2 + Margin)) );  
   }

   int decodeButton(int AnalogValue)
   {                                            // Assuming a resistor ladder of 9 equal resistors, use 9x 1K resistor selected 5% or normal 1% type
      static const int Table[] =                // Change this table for more or less switches, up to 20 switches is possible on an analog input with 1% resistors.
      {  1024 * 0 / 9,                           
         1024 * 1 / 9, 
         1024 * 2 / 9, 
         1024 * 3 / 9, 
         1024 * 4 / 9, 
         1024 * 5 / 9, 
         1024 * 6 / 9, 
         1024 * 7 / 9, 
         1024 * 8 / 9, 
         1024 * 9 / 9, 
      };
      
      for(int i = 0; ; i++)
      {  if(i >= 10)
         {  return 0;
         }
         if(near(AnalogValue, Table[i]))
         {  return i;
         }
      }
   }

   int           m_PinNr;
   unsigned long m_Timer;
   int           m_LastValue;
   int           m_Counter;
};


ANALOG_BUTTON_GROUP GroepA1;                    // As an example, three groups of switches have been created, which can be reduced or expanded as required
ANALOG_BUTTON_GROUP GroepA2;                    // Don't forget to create an equal amount of GroupAx.setup(Ax) in "void setup()"
ANALOG_BUTTON_GROUP GroepA3;                    // Also in the "void loop()" an button action piece is necessary for each buttongroup

void setup()
{
   Serial.begin(9600);
   
   GroepA1.setup(A3);                           // Swtich GroupA1 uses the analog input A3 in this case, can be changed to any analog input
   GroepA2.setup(A4);                           // Swtich GroupA2 uses the analog input A4 in this case, can be changed to any analog input
   GroepA3.setup(A5);                           // Swtich GroupA3 uses the analog input A5 in this case, can be changed to any analog input
}

void loop() 
{
   int SwitchNr;

   if(GroepA1.check(SwitchNr))
   {  Serial.print("- GroepA1, SwitchNr "); Serial.println(SwitchNr);

// -------------------------------------------------------------------
// Action for the first group of switches: ANALOG_BUTTON_GROUP GroepA1
// -------------------------------------------------------------------
   
      if(SwitchNr == 1)
      {  // Code voor GroepA1 SwitchNr 1
      }
      if(SwitchNr == 2)
      {  // Code voor GroepA1 SwitchNr 2
      }
      if(SwitchNr == 3)
      {  // Code voor GroepA1 SwitchNr 3
      }
      if(SwitchNr == 4)
      {  // Code voor GroepA1 SwitchNr 4
      }  
      if(SwitchNr == 5)
      {  // Code voor GroepA1 SwitchNr 5
      }
      if(SwitchNr == 6)
      {  // Code voor GroepA1 SwitchNr 6
      }
      if(SwitchNr == 7)
      {  // Code voor GroepA1 SwitchNr 7
      }
      if(SwitchNr == 8)
      {  // Code voor GroepA1 SwitchNr 8
      }  
      if(SwitchNr == 9)
      {  // Code voor GroepA1 SwitchNr 9
      }

// --------------------------------------------------------------------
// Action for the second group of switches: ANALOG_BUTTON_GROUP GroepA2
// --------------------------------------------------------------------

      if(SwitchNr == 1)
      {  // Code voor GroepA2 SwitchNr 1
      }
      if(SwitchNr == 2)
      {  // Code voor GroepA2 SwitchNr 2
      }
      if(SwitchNr == 3)
      {  // Code voor GroepA2 SwitchNr 3
      }
      if(SwitchNr == 4)
      {  // Code voor GroepA2 SwitchNr 4
      }  
      if(SwitchNr == 5)
      {  // Code voor GroepA2 SwitchNr 5
      }
      if(SwitchNr == 6)
      {  // Code voor GroepA2 SwitchNr 6
      }
      if(SwitchNr == 7)
      {  // Code voor GroepA2 SwitchNr 7
      }
      if(SwitchNr == 8)
      {  // Code voor GroepA2 SwitchNr 8
      }  
      if(SwitchNr == 9)
      {  // Code voor GroepA2 SwitchNr 9
      }

// --------------------------------------------------------------------
// Action for the second group of switches: ANALOG_BUTTON_GROUP GroepA3
// --------------------------------------------------------------------
   
      if(SwitchNr == 1)
      {  // Code voor GroepA3 SwitchNr 1
      }
      if(SwitchNr == 2)
      {  // Code voor GroepA3 SwitchNr 2
      }
      if(SwitchNr == 3)
      {  // Code voor GroepA3 SwitchNr 3
      }
      if(SwitchNr == 4)
      {  // Code voor GroepA3 SwitchNr 4
      }  
      if(SwitchNr == 5)
      {  // Code voor GroepA3 SwitchNr 5
      }
      if(SwitchNr == 6)
      {  // Code voor GroepA3 SwitchNr 6
      }
      if(SwitchNr == 7)
      {  // Code voor GroepA3 SwitchNr 7
      }
      if(SwitchNr == 8)
      {  // Code voor GroepA3 SwitchNr 8
      }  
      if(SwitchNr == 9)
      {  // Code voor GroepA3 SwitchNr 9
      }

  }

}

Gegroet,
Bram

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

Ja, dat was de bedoeling, om voor elke switch een if statement te hebben. Dan kun je daar nog code aan toevoegen om de gewenste aktie uit te voeren.

Maar je moet nog wel de analoge port inlezen en de procedure uitvoeren om te testen of er een toets is ingedrukt.

Dus bij

code:


// --------------------------------------------------------------------
// Action for the second group of switches: ANALOG_BUTTON_GROUP GroepA2
// --------------------------------------------------------------------

Moet je dan nog een stukje toevoegen:

code:


   }

   if(GroepA2.check(SwitchNr))
   {  Serial.print("- GroepA2, SwitchNr "); Serial.println(SwitchNr);

En dat dan ook voor GroepA3

blackdog

Golden Member

Hi,

Ik heb het schaklaar schema ook aangepast, er is maar één weerstands string nodig voor alle groepen, daar de weerstands string niet wordt belast.
Zoals ook al in de code staat, kan je de hoeveelheid strings gebruiken (analoge ingang groepen) die je nodig hebt.
Ook hoef je voor iedere groep geen negen schakelaars te gebruiken twee of zeven kan ook.

Let wel op met de analoge ingangen, als er geen schaklaar is ingedrukt, is de impedantie in de lage frequenties rond de 220K met 1nF parallel.
Dus bij lange bedrading kunnen de ingangs draden storingen oppikken, dus zoals altijd let op je bedradings techniek.

http://www.bramcam.nl/Diversen/Arduino-Analog-Button-03.png

.
De code heb ik ook aangepast zoals deKees al aangaf, zie hieronder de de laangepaste vrsie.

c code:


/*  Multi group Analog button selector
 * 
 * Created      : December, 2019
 * By           : CJ van der Hoeven
 *
 * Purpose      : Reading out multiple switches on a single analog input of an Arduino (here as an example 9x one switch per input in three groups)
 *              :
 *              :
 * Featuring    : Multiple customizable to more or less groups and also more or less switches per group 
 *                
 * The code has been adapted for my application.      
 * Blackdog, www.circuitsonline.net Netherlands
 * 
 * The code is owned by: CJ van der Hoeven
 *                
 */


class ANALOG_BUTTON_GROUP
{
public:
   void setup(int PinNr)
   {  m_PinNr = PinNr;
   }

   bool check(int &Action)
   { 
      if(m_Timer != millis())
      {  m_Timer = millis();
      
         int NewValue = analogRead(m_PinNr);
         if(m_Counter < 0)
         {  if(near(NewValue,0))
            m_Counter += 1;
         }
         else
         {  if( near(NewValue, m_LastValue) )
            {  const int MaxDebounce = 50; 
               if( m_Counter < MaxDebounce)
               {  // Same value multiple times in a row
                  m_Counter += 1;
               }   
               else
               {  Action = decodeButton(m_LastValue);
                  if(Action != 0)
                  {  m_Counter = -50;
                     return true;
                  }
               }
            }
            else
            {  // Value has changed. Register new value and restart counter.
               m_LastValue = NewValue;
               m_Counter = 0;
            }
         }
      }
      return false;
   }

   bool near(int x1, int x2)
   {  int Margin = 20;                          // this helps with the precision of the resistor divider and the inaccuracy of the ADC, the measured value of a switch can be between +20 and -20 LSB of the ADC.
      return ((x1 > (x2 - Margin)) && (x1 < (x2 + Margin)) );  
   }

   int decodeButton(int AnalogValue)
   {                                            // Assuming a resistor ladder of 9 equal resistors, use 9x 1K resistor selected 5% or normal 1% type
      static const int Table[] =                // Change this table for more or less switches, up to 20 switches is possible on an analog input with 1% resistors.
      {  1024 * 0 / 9,                           
         1024 * 1 / 9, 
         1024 * 2 / 9, 
         1024 * 3 / 9, 
         1024 * 4 / 9, 
         1024 * 5 / 9, 
         1024 * 6 / 9, 
         1024 * 7 / 9, 
         1024 * 8 / 9, 
         1024 * 9 / 9, 
      };
      
      for(int i = 0; ; i++)
      {  if(i >= 10)
         {  return 0;
         }
         if(near(AnalogValue, Table[i]))
         {  return i;
         }
      }
   }

   int           m_PinNr;
   unsigned long m_Timer;
   int           m_LastValue;
   int           m_Counter;
};


ANALOG_BUTTON_GROUP GroepA1;                    // As an example, three groups of switches have been created, which can be reduced or expanded as required
ANALOG_BUTTON_GROUP GroepA2;                    // Don't forget to create an equal amount of GroupAx.setup(Ax) in "void setup()"
ANALOG_BUTTON_GROUP GroepA3;                    // Also in the "void loop()" an button action piece is necessary for each buttongroup

void setup()
{
   Serial.begin(9600);
   
   GroepA1.setup(A3);                           // Swtich GroupA1 uses the analog input A3 in this case, can be changed to any analog input
   GroepA2.setup(A4);                           // Swtich GroupA2 uses the analog input A4 in this case, can be changed to any analog input
   GroepA3.setup(A5);                           // Swtich GroupA3 uses the analog input A5 in this case, can be changed to any analog input
}

void loop() 
{
   int SwitchNr;

   if(GroepA1.check(SwitchNr))
   {  Serial.print("- GroepA1, SwitchNr "); Serial.println(SwitchNr);
// -------------------------------------------------------------------
// Action for the first group of switches: ANALOG_BUTTON_GROUP GroepA1
// -------------------------------------------------------------------
   
      if(SwitchNr == 1)
      {  // Code voor GroepA1 SwitchNr 1
      }
      if(SwitchNr == 2)
      {  // Code voor GroepA1 SwitchNr 2
      }
      if(SwitchNr == 3)
      {  // Code voor GroepA1 SwitchNr 3
      }
      if(SwitchNr == 4)
      {  // Code voor GroepA1 SwitchNr 4
      }  
      if(SwitchNr == 5)
      {  // Code voor GroepA1 SwitchNr 5
      }
      if(SwitchNr == 6)
      {  // Code voor GroepA1 SwitchNr 6
      }
      if(SwitchNr == 7)
      {  // Code voor GroepA1 SwitchNr 7
      }
      if(SwitchNr == 8)
      {  // Code voor GroepA1 SwitchNr 8
      }  
      if(SwitchNr == 9)
      {  // Code voor GroepA1 SwitchNr 9
      }
   }
   
// --------------------------------------------------------------------
// Action for the second group of switches: ANALOG_BUTTON_GROUP GroepA2
// --------------------------------------------------------------------
   if(GroepA2.check(SwitchNr))
   {  Serial.print("- GroepA2, SwitchNr "); Serial.println(SwitchNr);
      
      if(SwitchNr == 1)
      {  // Code voor GroepA2 SwitchNr 1
      }
      if(SwitchNr == 2)
      {  // Code voor GroepA2 SwitchNr 2
      }
      if(SwitchNr == 3)
      {  // Code voor GroepA2 SwitchNr 3
      }
      if(SwitchNr == 4)
      {  // Code voor GroepA2 SwitchNr 4
      }  
      if(SwitchNr == 5)
      {  // Code voor GroepA2 SwitchNr 5
      }
      if(SwitchNr == 6)
      {  // Code voor GroepA2 SwitchNr 6
      }
      if(SwitchNr == 7)
      {  // Code voor GroepA2 SwitchNr 7
      }
      if(SwitchNr == 8)
      {  // Code voor GroepA2 SwitchNr 8
      }  
      if(SwitchNr == 9)
      {  // Code voor GroepA2 SwitchNr 9
      }
   }
   
// --------------------------------------------------------------------
// Action for the third group of switches: ANALOG_BUTTON_GROUP GroepA3
// --------------------------------------------------------------------
   if(GroepA3.check(SwitchNr))
   {  Serial.print("- GroepA3, SwitchNr "); Serial.println(SwitchNr);   

      if(SwitchNr == 1)
      {  // Code voor GroepA3 SwitchNr 1
      }
      if(SwitchNr == 2)
      {  // Code voor GroepA3 SwitchNr 2
      }
      if(SwitchNr == 3)
      {  // Code voor GroepA3 SwitchNr 3
      }
      if(SwitchNr == 4)
      {  // Code voor GroepA3 SwitchNr 4
      }  
      if(SwitchNr == 5)
      {  // Code voor GroepA3 SwitchNr 5
      }
      if(SwitchNr == 6)
      {  // Code voor GroepA3 SwitchNr 6
      }
      if(SwitchNr == 7)
      {  // Code voor GroepA3 SwitchNr 7
      }
      if(SwitchNr == 8)
      {  // Code voor GroepA3 SwitchNr 8
      }  
      if(SwitchNr == 9)
      {  // Code voor GroepA3 SwitchNr 9
      }
  }
}

Nu weer verder met de andere projectjes, niet te veel tijd door werkdruk. :-)

Groet,
Bram

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

Ja, inderdaad. 1 string weerstanden is genoeg voor alle drie de groepen.

Ziet er goed uit zo.