Adressing variable using a string and an int in Arduino - variables

I wonder how I can address a variable by putting together a string and an int in Arduino.
I´m using many variables of the same type and with almost the same name. I´m just append a number to each variable.
The names of the variables are e.g. int sensorValue_1; int sensorValue_2; and so on.
I´d like to write less because my code is becoming too long.
When addressing the variables, I´d like to write something like this: sensorValue_[+ intVariable];
Here is an example of what I mean:
int sensorIndex_1 = 1;
int sensorIndex_2 = 2;
int sensorIndex_3 = 3;
int sensorValue_1;
int sensorValue_2;
int sensorValue_3;
void setup()
{
Serial.begin(9600);
}
void loop()
{
doSomething(sensorIndex_1);
//doSomething(sensorIndex_2);
//doSomething(sensorIndex_3);
}
void doSomething(int sensorIndex)
{
if(sensorIndex == 1)
{
Serial.print("Sensor 1: ");
sensorValue_1 = analogRead(A1);
Serial.println(sensorValue_1);
}
if(sensorIndex == 2)
{
Serial.print("Sensor 2: ");
sensorValue_2 = analogRead(A2);
Serial.println(sensorValue_2);
}
if(sensorIndex == 3)
{
Serial.print("Sensor 3: ");
sensorValue_3 = analogRead(A3);
Serial.println(sensorValue_3);
}
delay(1000);
}
And I want to shorten the code in the doSomething() method.
I want to have something like this:
Notice the "[+ sensorIndex]"
void doSomething(int sensorIndex)
{
Serial.print("Sensor [+ sensorIndex]: ");
sensorValue_[+ sensorIndex] = analogRead(A[+ sensorIndex]);
Serial.println(sensorValue_[+ sensorIndex]);
delay(1000);
}
By the way: I´d like to avoid for-loops, if possible.
In my case, the code would become too complicated.
How do I manage this?

User2461391 has a great start but the rest of the puzzle I think you want is:
int array1[3];
int array2[3];
int arrayx[3];
void setup()
{
}
void loop()
{
int index=1;
array1[2]=doSomething(2);
arrayx[index]=doSomething(index);
Serial.print("Sensor ");
Serial.print(index);
Serial.print(": ");
Serial.println(arrayx[index]);
while(1);
}
int doSomething(int sensorIndex) // It probably makes more sense to return the value
{
return (analogRead(sensorIndex));
}

You don't need to use A1 and A2 and the likes to define the analog pin you want to read. Just 1 or 2 will do.
void doSomething(int sensorIndex)
{
Serial.print("Sensor ");
Serial.print(sensorIndex);
Serial.print(": ");
sensorValue = analogRead(sensorIndex);
Serial.println(sensorValue);
delay(1000);
}

Related

Arduino - passing values by reference from lamda to singleton

Hello i am bigginer in programing and i have specific problem.
I have been learning a new ways to write a code in small Arduino project.
that project have multiple objects like distance measuring Senzor, led diods , temperature senzor, etc. And all this objects have its own menu where you can, for example, start a calibration or just get values.
What i need is singleton class that has a function enter_esc() that need a int (*funct)() parameter basically function pointer.
That enter_esc(int (*funct)()) function just looping function until you press escape pin which is defined.
function Calibration() have inside some private: object data types like value or cali_value.
so i tried to insert function Calibration() right into enter_esc(Calibration) but it won't compile becouse i didnt pass that vlaues by reference or copy.
but what i found is lambda.
i made a lamda similar to a Calibration() function and i passed values by reference &{//domething;}
but i had to use enter_esc(std::function<int()>& funct) whitch is only int C++ standard library and not in Arduino C/C++ so my qestion is:
[is there some way how to pass values by reference by using lambda to a singleton class in Arduino ?]
(i konw it can be done differently but like i said i want to learn some new ways to program, also if you have some different way to make it i will by very happy to see it)
10Q for your time :)
//Class.h
#pragma once
class events {
private:
static events e_instance;
int p_menu, p_enter, p_esc, p_up, p_down;
int menuValue;
events();
public:
events(const events&) = delete;
static events& Get();
int ArrowUpDown(int maxVal);
int ArrowUpDown(int p_up, int p_down, int maxVal);
int enter_esc(const std::function<int()>& funct);
};
events events::e_instance;
class deviceBase : public Printables
{
public:
const char* a_pin;
int d_pin;
String type;
String deviceName;
bool inUse;
int actualCount;
public:
String getType() override;
int getActualCount() override;
String getName() override;
String getInUse() override;
};
class senzor : public deviceBase
{
private:
int Value;
int triggValue;
public:
int p_triggValue = 10;
static int allSenzors;
friend events;
senzor();
~senzor();
public:
int getValue();
int Calibration();
void changeTriggVal(int x);
void Reset();
void nullCalibration();
void Menu(int x);
void setName(String deviceName);
void setInUse(bool x);
int getPin();
};
int senzor::allSenzors = 0;
if you have some good advice to my code writing i will be also very glad
//Class.cpp
#include <iostream>
#include <string>
#include <functional>
#define LOG(x) std::cout << x << std::endl;
#define PINMENU 12
#define PINENTER 8
#define PINESC 9
#define PINUP 11
#define PINDOWN 13
using String = std::string;
struct Printables
{
virtual String getType() = 0;
virtual int getActualCount() = 0; ;
virtual String getName() = 0;
virtual String getInUse() = 0;
};
#include "Class.h"
events& events::Get() {
return e_instance;
}
int events::ArrowUpDown(int maxVal) {
if (maxVal) {
menuValue = menuValue < maxVal ? menuValue++ : menuValue;
}
if (maxVal) {
menuValue = menuValue > 0 ? menuValue-- : menuValue;
}
return menuValue;
}
int events::enter_esc(const std::function<int()>&funct) {
if (1) {
while (!p_esc) {
auto f = funct;
}
}
return 1;
}
int events::ArrowUpDown(int p_up, int p_down, int maxVal) { return 666; }
events::events() {};
String deviceBase::getType() { return type; }
int deviceBase::getActualCount() { return actualCount; }
String deviceBase::getName() { return deviceName; }
String deviceBase::getInUse() {
String Status;
Status = inUse == 1 ? "Active" : "Deactive";
return Status;
}
senzor::senzor() : Value(0), triggValue(1) {
a_pin = "xx";
type = "[SENZOR]";
deviceName = "[UNKNOWN]";
inUse = 0;
allSenzors++;
actualCount = allSenzors;
a_pin = 0;
}
senzor::~senzor() {
allSenzors = 0;
}
int senzor::getValue() {
Value = 4;
return Value;
}
int senzor::Calibration() {
triggValue = triggValue < getValue() ? getValue() : triggValue;
p_triggValue = triggValue;
return p_triggValue;
}
void senzor::changeTriggVal(int x) {
p_triggValue = x;
}
void senzor::Reset() {
p_triggValue = triggValue;
}
void senzor::nullCalibration() {
triggValue = 1;
}
void senzor::setName(String deviceName) {
this->deviceName = deviceName;
}
void senzor::setInUse(bool x) {
inUse = x;
}
int senzor::getPin() {
return 4;
}
int printsss() {
return 1;
}
////////////////////////////////this what i was writing about//////////////////////////////
void senzor::Menu(int x) {
events::Get().enter_esc([&]() { triggValue = triggValue < getValue() ? getValue() : triggValue;
p_triggValue = triggValue;
return p_triggValue; });
}
but if i use lambda in arduino with enter_esc(int (*funct)()) i get this kind of error
no matching function for call to 'events::enter_esc(senzor::Menu(int)::<lambda()>)'

Function not working when inside if or switch statements

I need to solve a OOP problem in which I have to manage multiple classes inherited by each other. First I need to read all the data for all the Employees of a Company. The reading runs very well but I also need to display the read data after reading the command 1 (I need to use switch). I created a function "afisare_angajati()" which only works outside "if" and "switch" statements. I don't know why those statements disable my function. This happened to me before but I couldn't find the cause. Is something that I am not seeing? You can see my function at the end of the code. Thx for help.
#include<iostream>
#include<string>
#include<vector>
class Angajat{
protected:
std::string nume;
float salariu_baza;
std::string functie;
float procent_taxe_salariu;
public:
float get_salariu_net(){return 0;}
float get_salariu_brut(){return 0;}
std::string get_nume(){return 0;}
void marire_salariu(){}
Angajat(std::string nume,float salariu_baza,std::string functie,float procent_taxe_salariu=40):
nume(nume),salariu_baza(salariu_baza),functie(functie),procent_taxe_salariu(procent_taxe_salariu){}
void display(){
std::cout<<nume<<'\n';
std::cout<<functie<<'\n';
}
};
class Analist:public Angajat{
public:
Analist(std::string nume,float salariu_baza,std::string functie,float procent_taxe_salariu=40):
Angajat(nume,salariu_baza,functie,procent_taxe_salariu){}
};
class Programator:public Analist{
protected:
float procent_deducere_salariu_it;
public:
Programator(std::string nume,float salariu_baza,std::string functie,float procent_taxe_salariu=40):
Analist(nume,salariu_baza,functie,procent_taxe_salariu){}
};
class LiderEchipaProgramare:public Programator{
protected:
int vechime;
float bonus_vechime;
public:
LiderEchipaProgramare(std::string nume,float salariu_baza,std::string functie,int vechime,float procent_taxe_salariu=40):
Programator(nume,salariu_baza,functie,procent_taxe_salariu),vechime(vechime){
bonus_vechime=500;
}
};
class FirmaProgramare{
private:
std::vector<Angajat*> vec_ang;
public:
void afisare_angajati(){
for(Angajat* a:vec_ang){
a->display();
}
}
void mareste_salarii(float,float,float){}
void promoveaza(std::string){}
void adauga_angajat(Angajat* a){
vec_ang.push_back(a);
}
};
int main(){
std::string nume;
std::string functie;
float salariu_baza;
int vechime;
int nr_ang,comanda;
FirmaProgramare pula;
std::cin>>nr_ang;
for(int i=0;i<nr_ang;++i){
std::cin.ignore();
std::getline(std::cin,nume);
std::cin>>functie;
std::cin>>salariu_baza;
Angajat* p = nullptr;
if(functie=="Analist"){
p = new Analist(nume,salariu_baza,functie);
}
else{
if(functie=="Programator"){
p = new Programator(nume,salariu_baza,functie);
}
else{
p = new LiderEchipaProgramare(nume,salariu_baza,functie,vechime);
}
}
pula.adauga_angajat(p);
}
std::cin>>comanda;
//pula.afisare_angajati(); output is correct if I put the function outside of brackets
switch(comanda)
{
case 1:{
pula.afisare_angajati();
break;
}
}
}

How can I write code to receive whole string from a device on rs232?

I want to know how to write code which receives specific string.for example, this one OK , in this I only need "OK" string.
Another string is also like OK
I have written code in keil c51 for at89s52 microcontroller which works but I need more reliable code.
I'm using interrupt for rx data from rs232 serial.
void _esp8266_getch() interrupt 4 //UART Rx.{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
else
{
count=0;
do
{
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data1) //rx_data1 = 0X0D /CR
{
RI=0;
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data2) // rx_data2 = 0x0A /LF
{
RI=0;
data_in_buffer=1;
if(loop_conti==1)
{
if(rec_bit_flag==1)
{
data_in_buffer=0;
loop_conti=0;
}
}
}
}
else
{
if(data_in_buffer==1)
{
received[count]=rx_buff; //my buffer in which storing string
rec_bit_flag=1;
count++;
loop_conti=1;
RI=0;
}
else
{
loop_conti=0;
rec_bit_flag=0;
RI=0;
}
}
}
while(loop_conti==1);
}
rx_buff=0;
}
This is one is just for reference, you need develop the logic further to your needs. Moreover, design is depends on what value is received, is there any specific pattern and many more parameter. And this is not a tested code, I tried to give my idea on design, with this disclaimer here is the sample..
//Assuming you get - "OK<CR><LF>" in which <CR><LF> indicates the end of string steam
int nCount =0;
int received[2][BUF_SIZE]; //used only 2 buffers, you can use more than 2, depending on how speed
//you receive and how fast you process it
int pingpong =0;
bool bRecFlag = FALSE;
int nNofbytes = 0;
void _esp8266_getch() interrupt 4 //UART Rx.
{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
if(RI) // Rx interrupt
{
received[pingpong][nCount]=SBUF;
RI =0;
if(nCount > 0)
{
// check if you receive end of stream value
if(received[pingpong][nCount-1] == 0x0D) && (received[pingpong][nCount] == 0x0A))
{
bRecFlag = TRUE;
pingpong = (pingpong == 0);
nNofbytes = nCount;
nCount = 0;
return;
}
}
nCount++;
}
return;
}
int main()
{
// other stuff
while(1)
{
// other stuff
if(bRecFlag) //String is completely received
{
buftouse = pingpong ? 0 : 1; // when pingpong is 1, buff 0 will have last complete string
// when pingpong is 0, buff 1 will have last complete string
// copy to other buffer or do action on received[buftouse][]
bRecFlag = false;
}
// other stuff
}
}

What is time complexity of below function?

int sumOfDigits(int n)
{
if(n<=9)
return n;
else
{
int r=0;
while(n!=0)
{
r=r+n%10;
n=n/10;
}
sumOfDigits(r);
}
}
This function finds sum of digits of a number till it becomes less than 10.
e.g.if n=12345
then output=6
as 1+2+3+4+5=15,
again 1+5=6.
I guess what you try to achieve is something like this:
class St2 {
static int sumOfDigits(int n) {
if(n<=9) {
return n;
}
else {
int d = n%10;
return d + sumOfDigits((n-d)/10);
}
}
public static void main(String[] args) {
System.out.println(St2.sumOfDigits(345678));
}
}
This would sum the digits. The complexity is linear in the number of digits thus logarithmic in the scale of the input number.

How do I properly write out a JUnit test for a method that counts how many e's are in a string?

Here is the method I have defined that is supposed to accept a String as input and should return the number of times the char 'e' occurs as an int:
public int count_e(String input){
int count = 0;
for (int i = 0;i<input.length();i++){
char e = 'e';
if (input.charAt(i)==e){
count=count+1;
i++;
return count;
}
else{
count=count+1;
i++;
}
}
return count;
}
}
I am trying to write a JUnit test to see if I can input a string into the method and return the correct number of e's. Below is my test, and at the moment I keep getting an error saying that my method count_e is undefined for type String.
Can someone tell me why it is coming up as undefined?
#Test
public void testCount_e() {
String input= "Isabelle";
int expected= 2;
int actual=input.count_e();
assertTrue("There are this many e's in the String.",expected==actual);
}
}
You failed to pass anything to your count_e method!
How about something like:
#Test
public void testCount_e() {
String input = "Isabelle";
int expected = 2;
int actual = count_e(input);
Assert.assertEqual("There are this many e's in the String.", expected, actual);
}
For a unit test, you could probably shorten it to:
#Test
public void testCount_e() {
Assert.assertEqual("There are this many e's in the String.", count_e("Isabelle"), 2);
}