Keypad 4x4 in Arduino - c++

Can anyone explain to me what is the meaning of this code :
byte rowPins[numRows] = {9, 8, 7, 6}; //Rows 0 to 3
byte colPins[numCols]= {5, 4, 3, 2}; //Columns 0 to 3
How do they get the number of {9, 8, 7, 6} and {5, 4, 3, 2}. Here is the full code:
/*4x4 Matrix Keypad connected to Arduino
This code prints the key pressed on the keypad to the serial port*/
#include <Keypad.h>
const byte numRows= 4; //number of rows on the keypad
const byte numCols= 4; //number of columns on the keypad
//keymap defines the key pressed according to the row and columns just as appears on the keypad
char keymap[numRows][numCols]= {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
//Code that shows the the keypad connections to the arduino terminals
byte rowPins[numRows] = {9, 8, 7, 6}; //Rows 0 to 3
byte colPins[numCols]= {5, 4, 3, 2}; //Columns 0 to 3
//initializes an instance of the Keypad class
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
void setup() {
Serial.begin(9600);
}
//If key is pressed, this key is stored in 'keypressed' variable
//If key is not equal to 'NO_KEY', then this key is printed out
//if count=17, then count is reset back to 0 (this means no key is pressed during the whole keypad scan process
void loop() {
char keypressed = myKeypad.getKey();
if (keypressed != NO_KEY) {
Serial.print(keypressed);
}
}

Everything in the code seems easy to understand. Along with the comment it is clear as a crystal. But as you said, you need an explanation, I will provide an answer :
const byte numRows= 4; //number of rows on the keypad
const byte numCols= 4; //number of columns on the keypad
In the above given piece of code, two byte vaiables would be declared named numRows and numCols and initialized each with the value 4.
byte rowPins[numRows] = {9, 8, 7, 6}; //Rows 0 to 3
byte colPins[numCols]= {5, 4, 3, 2}; //Columns 0 to 3
So here is the code that you are stuck at. Two byte array would be declared named rowPins and colPins each of size 4 (since value of numRows and numCols are 4). Which would range from 0 to 3 (like array in c or java). In this numbers 9,8,7,6 would be assigned to array rowPins and 5,4,3,2 will be assigned to array colPins. Now how or where will these values be. They will be stored in a sequential way from index 0 to index 3. i.e
rowPins[0]=9
rowPins[1]=8
rowPins[2]=7
rowPins[3]=6
colPins[0]=5
colPins[1]=4
colPins[2]=3
colPins[3]=2
This is how they get those numbers.

They are not getting the numbers they are assigning it to the arduino pins 2,3,4,5,6,7,8,9
byte rowPins[numRows] = {9, 8, 7, 6}; //Rows 0 to 3
byte colPins[numCols]= {5, 4, 3, 2}; //Columns 0 to 3
you can also use 4,5,6,7,8,9,10,11 pins too. Just check what pins you are assigning for the row and column inputs and then write the code according to it.

Related

C++ How to add two arrays of unequal sizes using the for loop?

So the aim is to take two arrays as shown below
int x[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int k[4] = {1, 2, 3, 4};
and add each element of k to each element of x in a loop as shown
1 2 3 4 5 6 7 8 9 10
+1 +2 +3 +4 +1 +2 +3 +4 +1 +2
This should give us a final array [2, 4, 6, 8, 6, 8, 10, 12, 10, 12].
Any suggestions as to how I could achieve this in C++
Loop through the indexes of the larger array, using the modulus (%) operator to wrap-around the indexes when accessing the smaller array.
int x[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int k[4] = {1, 2, 3, 4};
int res[10];
for (int i = 0; i < 10; ++i) {
res[i] = x[i] + k[i % 4];
}
Online Demo
With % you can have the wrap-around behavior and with std::size(from C++17 onwards) the size of the array.
#include <algorithm>
#include <iostream>
int main()
{
int x[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int k[4] = {1, 2, 3, 4};
for(int i = 0; i < std::size(x); ++i)
{
x[i] = x[i] + k[i%std::size(k)];
}
//lets confirm if x has the right elmennts
for(const int& element: x)
{
std::cout<< element<<std::endl;
}
}
Note that here i have not used a separate array to store the resulting array. Instead the elements are added into the original array x. Storing the result in a new array is trivial.

Is there any efficient way to do "shuffling" of vector

I have a large size unsorted array, each element contains a unique integer number,
std::vector<size_t> Vec= {1, 5, 3, 7, 18...}
I need to shuffle the vector in such a way, given a specific number, look for it and then swap it with the number in a new desired position. This swapping needs to be done many times.
Currently I use anther vector PositionLookup to remember&update the positions after every swapping. And I'm wondering is there any more efficient way/data structure that can help do this?
Current solution,
//look for a specific number "key" and swap it with the number in desired position "position_new"
void shuffle(key, position_new)
{
size_t temp = Vec[position_new]; // main vector
size_t position_old = PositionLookup[key]; // auxiliary vector
Vec[position_old] = temp;
PositionLookup[temp] = position_old;
Vec[position_new] = key;
PositionLookup[key] = position_new;
}
A couple microoptimizations to start with: If the vector has a fixed size, you could use a std::array or a plain C array instead of a std::vector. You can also use the most compact integer type that can hold all the values in the vector (e.g. std::int8_t/signed char for values in the interval [-128,127], std::uint16_t/unsigned short for values in the interval [0,65535], etc.)
The bigger optimization opportunity: Since the values themselves never change, only their indexes, you only need to keep track of the indexes.
Suppose for simplicity's sake the values are 0 through 4. In that case we can have an array
std::array<std::int8_t, 5> indices{{2, 3, 1, 4, 0}};
Which represents the index of its indices in an imaginary array, here 4, 2, 0, 1, 3. Or in other words indices[0] is 2, which is the index of 0 in the imaginary array.
Then to swap the positions of 0 and 1 you only need to do
std::swap(indices[0], indices[1]);
Which makes the indices array 3, 2, 1, 4, 0 and the imaginary array 4, 2, 1, 0, 3.
Of course the imaginary array's values might not be the same as its indices.
If the (sorted) values are something like -2, -1, 0, 1, 2 you could obtain the value from the index by adding 2, or if they're 0, 3, 6, 9, 12 you could divide by 3, or if they're -5, -3, -1, 1, 3 you could add 5 then divide by 2, etc.
If the values don't follow a defined pattern, you can create a second array to look up the value that goes with an index.
std::array<std::int8_t, 5> indices{{2, 3, 1, 4, 0}};
constexpr std::array<std::int8_t, 5> Values{{1, 3, 5, 7, 18}};
// Imaginary array before: 18, 5, 1, 3, 7
std::swap(indices[0], indices[1]);
// Imaginary array after: 18, 5, 3, 1, 7
const auto index_to_value = [&](decltype(indices)::value_type idx) noexcept {
return Values[idx];
};
const auto value_to_index = [&](decltype(Values)::value_type val) noexcept {
return std::lower_bound(Values.begin(), Values.end(), val)
- Values.begin();
};
It's the same thing if the values aren't known until runtime, just obviously the values lookup table can't be const or constexpr.
std::array<std::int8_t, 5> indices{{2, 3, 1, 4, 0}};
std::array<std::int8_t, 5> values; // Not known yet at compile-time
// ... set `values` at runtime to e.g. -93, -77, -64, 8, 56
// Imaginary array before: 56, -64, -93, -77, 8
std::swap(indices[0], indices[1]);
// Imaginary array after: 56, -64, -77, -93, 8
const auto index_to_value = [&](decltype(indices)::value_type idx) noexcept {
return values[idx];
};
const auto value_to_index = [&](decltype(values)::value_type val) noexcept {
return std::lower_bound(values.cbegin(), values.cend(), val)
- values.cbegin();
};

Efficient C++ way to shift a cv::Mat with OpenCV

What is an efficient way to "shift" an OpenCV cv::Mat?
With shift I mean that if I have a row like this
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
and I shift it by 3 positions, I will get a row like this
3, 4, 5, 6, 7, 8, 9, 0, 1, 2
Now I am using this function:
void shift( const cv::Mat& in, cv::Mat& out, int shift )
{
if ( shift < 0 || shift > in.cols ) return;
if ( shift == 0 || shift==in.cols ) {
out = in.clone();
} else {
cv::hconcat(in(cv::Rect(shift,0,in.cols-shift,in.rows)),in(cv::Rect(0,0,shift,in.rows)),out);
}
}
but I am looking for a more efficient way.
If size of your array is not so big and rows=1 then you can repeat your array like this
0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9
Then for shifting it shift array's datapointer

Fill vector with random unique integers from a fixed pool of numbers

I want to fill a vector with random integers but there can't be duplicates in it.
First off, I have this code to put numberOfSlots random integers between 0 and 7 in the vector (numberOfSlots can be 2 to 20):
srand((unsigned int)time(NULL));
unsigned int min = 0;
unsigned int max = 7;
std::vector<unsigned int> v;
for (int i = 0; i < numberOfSlots; i++) {
unsigned int rdm = std::rand() % (max - min + 1) + min;
v.push_back(rdm);
}
This is the code for when duplicate integers are allowed. This is working fine!
Now I want to the change that code so that from the same random pool of possible integers (min to max) the generated random integer is only added if it's not already in the vector.
So if for example numberOfSlots is 5, then the vector will have 5 entries that were randomly chosen from the pool but are not the same, e.g. 7, 1, 3, 5, 0. If numberOfSlots is 8, the vector will be for example 3, 1, 2, 7, 6, 0, 4, 5.
I know how to shuffle the vector and stuff but I am not able to get this working. I think I have to use a while loop and check all already existing integers in the vector against the new random to be added number and if it's already in there generate a new random number and check again, etc. but I don't know
I am a beginner and this is really hard. Can someone maybe give me a hint? I would appreciate it... thank you so much
You can populate your vector with values 0..N-1 (or your pool values), and thereafter shuffle it. See example:
// Initialize
for(i = 0; i < N; i++)
arr[i] = i;
// shuffle
for(i = N - 1; i > 0; i--) {
j = rand() % i;
swap(arr[i], arr[j]);
}
I think your best bet is to create a vector to store the unrandomized integers, then another vector to store a randomized subset.
randomly chooose a number from your unrandomized integer vector, add that number to the randomized subset vector, then remove it from your unrandomized integer vector.
Now your unrandomized integer vector is one smaller, so randomly choose a number on the new smaller vector, add it to the randomized subset vector, and remove it from the unrandomized vector. Repeat.
Here's what it might look like
Unrandomized
{0, 1, 2, 3, 4, 5, 6, 7}
Randomized
{}
Choose random index: 5
Yields =>
Unrandomized
{0, 1, 2, 3, 5, 6, 7} //Removed 4 because it was at index #5
Randomized
{5}
Choose Random Index: 0
Yields =>
Unrandomized
{1, 2, 3, 5, 6, 7}
Randomized
{5, 0}
Choose Random Index: 6
Yields=>
Unrandommized
{1, 2, 3, 5, 6} // 7 removed at index #6
Randomized
{5, 0, 7}
And say you only have to pick do 3 random values here so you end up with 5, 0, 7. This method ensures no duplicates. I think there is an easier way using an inline function but I don't know it and the above should suffice.

swapping 2 numbers in 2 dimensional array

My question is as follows:
Refer to the following array declaration in the main():
const int size = 4;
int x[size][size] = {{1, 2, 3, 4}, {5, 6, 7, 8},
{9, 8, 7, 3}, {2, 1, 7, 1}};
Write a function SwapRows() to swap two rows of the above 2D array. For
example, if the function has been called to swap the first and the second rows of the
above 2D array then the result would be that the first row now becomes {5, 6, 7, 8}
and the second row now becomes {1, 2, 3, 4}. The function receives as parameter the
2D array, the size of the array, and two integers to indicate the rows to swap.
Help,,how can i go about this?????
Note: Using C++ Language
Pseudo code:
SwapRows(x[size][size], row0, row1, size)
for col = 0 to size - 1 do
temp = x[row0][col]
x[row0][col] = x[row1][col]
x[row1][col] = temp
Now all you need to do is convert the pseudo code into C++, then test, debug and document it.
#include <algorithm>
void SwapRows(int arr[][4], int r1, int r2)
{
std::swap(arr[r1],arr[r2]);
}