Arrays in Arduino - arrays

I am trying to create an array and be able to compare the second to last and last item in an array. It needs to be constantly adding and comparing to work correctly. This is just a function I am trying to get running to help control a stepper motor function. I have a loop that is going to fast for me to be able to compare directly. I do know that some of it is wrong but as I haven't coded in C very much I can't figure out how to use an array correctly. Thank you in advance.
int P[10],V[10],i,x,y;
Serial.print("checkvalue = ");
Serial.print(checkvalue);Serial.print("\n");
Serial.print("P = "); Serial.print(P[i]); Serial.print("\n"); //attempting to print array
Serial.print("V = "); Serial.print(V[i]); Serial.print("\n"); //to see if it is collecting
//data correctly
//these variables are declared above in my code, just didn't copy in
Dgreadpb = digitalRead(13);
PBcheck = Dgreadpb;
//Serial.print("Button in = ");Serial.print(Dgreadpb); Serial.print("\n");
Dgreadvls = digitalRead(12);
VLScheck = Dgreadvls;
//Serial.print("Photo in = ");Serial.print(Dgreadvls); Serial.print("\n");
for (i = 0; i < 10; i++){
x = Dgreadpb;
y = Dgreadvls;
P[i] = x;
V[i] = y;
if (P[i-1] == P[i] && V[i-1] == V[i]){ //trying to compare second to
checkvalue == 0; //last term to the last term
return;
}
else if(P[i-1] != P[i] || V[i-1] != V[i]){
checkvalue == 1;
return;
}
}
delay (1000);

By "trying to compare second to last term to the last term", do you mean "Trying to compare second to last term with their previous"? If that's the case your indices are wrong, it should be for(i = 1; i<10; i++).
Also both conditions are opposite (Either both are equal or AT LEAST one of them is different), there is no need for else if. Even more, cause both conditions are opposite it will never complete the loop. I think that's not the intention, if you're trying to say that only one of them are different you should do:
if (P[i-1] == P[i] && V[i-1] == V[i]){ //If both are equal
checkvalue == 0;
return;
}
else if(P[i-1] == P[i] || V[i-1] == V[i]){ //If only one is equal
checkvalue == 1;
return;
}

Ok, then I'd make a different thing.
Looking at your comment, it looks like you want to do something like this: read the value of two pins, compare them to the last value you read and, if they are differernt, start the motor, otherwise stop it.
Now, a lot of info are missing (e.g. how do you check the motor? how often do you want to check the sensor? what sensor?) but IMHO you should do something like this.
In this code I suppose that
you want to check the sensor every 100 milliseconds
if the values differ, you want to turn on the motor for the next 100 ms
the motor is a DC motor turned on by setting the corresponding pin (e.g. 10)
the sensors have a binary output on pins 12 and 13, since you wrote that in the code
BTW I used the millis() function because I hate the delay, since it blocks the uC. Using my function you'll be able to perform other operations while it is idle.
const byte motorPin = 10;
const byte sensorPPin = 12;
const byte sensorVPin = 13;
#define LOOP_TIME_MS 100
unsigned long lastLoopTime;
boolean lastPval, lastVval;
void setup()
{
pinMode(motorPin, OUTPUT);
pinMode(sensorPPin, INPUT);
pinMode(sensorVPin, INPUT);
lastPval = digitalRead(sensorPPin);
lastVval = digitalRead(sensorVPin);
lastLoopTime = millis();
}
void loop()
{
if ((millis() - lastLoopTime >= LOOP_TIME_MS)
{
boolean Pval = digitalRead(sensorPPin);
boolean Vval = digitalRead(sensorVPin);
if ((Pval != lastPval) || (Vval != lastVval))
{
digitalWrite(motorPin, HIGH);
}
else
{
digitalWrite(motorPin, LOW);
}
lastLoopTime += LOOP_TIME_MS;
}
/* Here you can do something else */
}
EDIT: If, on the other side, you want to use arrays (because you want to test the last N values instead of just the previous one) please provide further info on what are the changing conditions (or better provide examples)

Related

Finding maximum bitwise and value in a two faced card

There are a list of cards with two numbers on it, one on the front and one on the back. I need to maximize the bitwise-and (&) by either taking the front or back of each card. And yes it should be done in minimum flips possible, as initially the cards are facing front and when I pick the number at the back, I am making a flip. I have solved this problem using the following code:
for(int bit = 1<<30;bit > 0;bit>>=1){
bool possible = true;
//Setting state to '0' for not flipping and '1' for flipping.'-1' means unset
for(int i = 0;i < n;i++){
if(state[i]==0 && !(A[i]&bit))possible = false;//A is the array to store front value
else if(state[i]==1 && !(B[i]&bit))possible = false;// B is the array to store back value
else if(!(A[i]&bit) &&!(B[i]&bit))possible = false;
}
if(!possible)continue;
for(int i = 0;i < n;++i){**//SNIPPET TO REPLACE START**
if (state[i] != -1)continue;
if (!(A[i]&bit))state[i] = 1;
else if (!(B[i]&bit))state[i] = 0;//SNIPPET TO REPLACE END
}
/*USING THIS SNIPPET GIVED WRONG ANSWER
for(int i = 0;i < n;++i){
if(state[i]!=-1)continue;
if(A[i] & bit)state[i]=0;
else if(B[i] & bit)state[i]=1;
}
*/
}
int ans;
int count_ = 0;
ans = (1 << 30) - 1;
for(int i = 0;i < n;i++){
if(state[i]==1){
ans&=B[i];
count_++;
}
else ans&=A[i];
}
As explained in the comments of the code, I feel the both snippet should work just fine. I maybe missing some edge case why the snippet I commented does not work as the one I actually used in the code for execution.

In C language, comparing 2 members of a structure

I seem to have trouble with comparing 2 members of a structure.
I can see in watch window that the sequence in all logs are 0x000.
This one evaluates AllLogsNotZero to TRUE
for (i=0;(i<(3)&&(!AllLogsNotZero));i++)
{
UINT8 j;
j=i+1;
UINT16* comp1;
UINT16* comp2;
comp1 = (UINT16*) (&Data.log[i].Sequence);
comp2 = (UINT16*) (&Data.log[j].Sequence);
if ((Data.log[i].Sequence == Data.log[j].Sequence) == 0)
AllLogsNotZero=FALSE;
else
AllLogsNotZero=TRUE;
This one evaluates AllLogsNotZero to FALSE
for (i=0;(i<(3)&&(!AllLogsNotZero));i++)
{
UINT8 j;
j=i+1;
UINT16* comp1;
UINT16* comp2;
comp1 = (UINT16*) (&Data.log[i].Sequence);
comp2 = (UINT16*) (&Data.log[j].Sequence);
if (Data.log[i].Sequence == Data.log[j].Sequence)
AllLogsNotZero=FALSE;
else
AllLogsNotZero=TRUE;
I don't know why.
I think you're making a mountain out of a molehill. I think the way I'd write the loop using your current variable name is:
bool AllLogsNotZero = true;
for (int i = 0; i < 4; i++)
{
if (Data.log[i].Sequence == 0)
{
AllLogsNotZero = false;
break;
}
}
if (AllLogsNotZero)
…processing option for no zero logs
else
…processing option for at least one log zero
We can debate whether the loop limit should be 3 or 4 (or some other value); it isn't entirely clear from your code, but you set j to i+1 and use that, and limit i to < 3, so when the code doesn't use i+1, the limit should probably be 4. It would be better to have an enumeration or #define value for the limit — the name would indicate what you're measuring against better than just the number.
The negative in the name (AllLogsNotZero) also makes life harder; avoid that when you can. For example:
bool LogsZero = false;
for (int i = 0; i < 4; i++)
{
if (Data.log[i].Sequence == 0)
{
LogsZero = true;
break;
}
}
if (LogsZero)
…processing option for at least one log zero
else
…processing option for no zero logs
Look if statements
First check:
//You check if they are the same
if (Data.log[i].Sequence == Data.log[j].Sequence)
Second check
//You check if they are not the same
if ((Data.log[i].Sequence == Data.log[j].Sequence) == 0)
//Can be evaluated as:
if (Data.log[i].Sequence != Data.log[j].Sequence)
for (i=0;(i<(3)&&(!AllLogsNotZero));i++)
{
UINT16 Var1 = 0;
if (Data.log[i].Sequence == Var1)
AllLogsNotZero=FALSE;
else
AllLogsNotZero=TRUE;
This works!!

Minimax algorithm and checking every option / keeping track of best move in C

I try to make a tic tac toe game using minimax algorithm, but I have a hard time with recursion and keeping track of best move.
Now, my function returns a score when there is a winner, and then deletes that move from a board. My question is, how to prevent it to search the same child node again?
int minimax(Board *board, int depth, char player, Position lastPosition)
{
Position avMoves;
int score = -2;
if (didTheGameEnd(*board, (player == 'X') ? 'O' : 'X', lastPosition) == 1) {
return (depth % 2 != 0) ? -10 : 10;
} else if (didTheGameEnd(*board, (player == 'X') ? 'O' : 'X', lastPosition) == -1) {
return 0;
}
if (board->numberOfBlanks != 0) {
avMoves = getAvaliableMoves(*board);
}
for (int i = 0; i < board->numberOfBlanks; i++) {
int newScore;
placeMark(board, player, avMoves);
newScore = minimax(board, depth+1, changePlayer(player), avMoves);
if (depth % 2 != 0) {
if (newScore > score) {
score = newScore;
}
} else {
if (newScore < score) {
score = newScore;
}
}
board->boardArr[avMoves.y][avMoves.x] = '-';
board->numberOfBlanks++;
board->numberOfOccupied--;
}
return score;
}
How to return the best move ?
EDIT I forgot to add, that I try to make this on N size board
it may be helpful to look at the source code for Tom Kerrigan's "simple chess program" below
basically the following code is part of the alpha-beta (minmax) function. It generates the moves and loops over the moves in the for loop checking if there are any legal moves to be made (this is necessary as chess uses pseudo-legal move generators) part of the key to returning the best variation is use of a "triangular array" that collects the best variation in pv[0][0..pv_length[0]]. pv_length keeps track of the length of the best variation at various depth of the gametree. Its a tedious indexing scheme but gets the job done.
gen();
if (follow_pv) /* are we following the PV? */
sort_pv();
f = FALSE;
/* loop through the moves */
for (i = first_move[ply]; i < first_move[ply + 1]; ++i) {
sort(i);
if (!makemove(gen_dat[i].m.b))
continue;
f = TRUE;
x = -search(-beta, -alpha, depth - 1);
takeback();
if (x > alpha) {
/* this move caused a cutoff, so increase the history
value so it gets ordered high next time we can
search it */
history[(int)gen_dat[i].m.b.from][(int)gen_dat[i].m.b.to] += depth;
if (x >= beta)
return beta;
alpha = x;
/* update the PV */
pv[ply][ply] = gen_dat[i].m;
for (j = ply + 1; j < pv_length[ply + 1]; ++j)
pv[ply][j] = pv[ply + 1][j];
pv_length[ply] = pv_length[ply + 1];
}
}
/* no legal moves? then we're in checkmate or stalemate */
if (!f) {
if (c)
return -10000 + ply;
else
return 0;
}
/* fifty move draw rule */
if (fifty >= 100)
return 0;
return alpha;
}
How to return the best move?
You check each possible move and return the one with the best score. Of course as soon as you found a winning move you can return it immediately.
What makes it difficult is the design of your function. You would have to make the move and then call the function with the move that was made, revert it and test the next one. If you redesign your function to take nextPosition instead of lastPosition as parameter and then execute that move inside the function things will be a little easier.
How to prevent the same positions to be searched again?
Use a lookup table. A position can easily be represented by 18 bits, a single integer, e.g. by using the first 9 bits to say where the X pieces are and the next 9 bits where the O pieces are. It would be possible with fewer bits but then you need complicated en- and decoding.
X X -
- O - = 110 000 000 000 010 001 = 196625
- - O
I also suggest to have a look at alpha-beta pruning, with good move ordering (try the promising ones first) you can cut off whole branches and save a lot of time. For tic tac toe it doesn't matter, but as soon as it gets a little more complex it helps a lot.

Arduino integer array returns value of 3 for index 0 always

I wrote this sketch to send codes to a speakjet sound processor. It will store any number of three digit integers from 128 to 254. I type them into the serial monitor and hit enter after each one. it is stored in an array, and after 900 is entered, the values stored in the array are sent to the speakjet and also read back to the serial monitor. The issue I'm having is that the array will return a value of three for index 0 every time. I have no clue as to why this is.
Here is the code.
int in=0;
int code;
int phrase[] {};
int x=0;
String stack="";
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
Serial.println("Ready");
}
void loop() {
while (Serial.available()>0) {
int inbyte = Serial.read();
if (in<=2);
{
stack += (char)inbyte;
in++;
//Serial.println(stack);
//Serial.println(in);
}
if (in==3) {
if (stack == "900") {
for(int i=0;i<x;i++) {
Serial1.write(phrase[i]);
Serial.println(i);
Serial.println(phrase[i]);
Serial.println();
}
stack="";
x = 0;
in = 0;
Serial.println("Ready");
} else {
phrase[x]=0;
int code = stack.toInt();
if (code < 128) {
code = 253;
}
phrase[x]=code;
Serial.println(x);
Serial.println(phrase[x]);
x++;
in=0;
Serial.write(code);
Serial.println();
stack = "";
}
}
}
}
Thanks for any advice, or help with this matter.
Brewer.
well, first of all, I noticed while reformatting your code you've got a typo here:
if (in<=2); // <-- if the condition is true, it does nothing
{
// this block of code always gets executed
stack += (char)inbyte;
in++;
}
Then I find it really surprising that you can store anything at all in your array:
int phrase[] {};
as it is allocated no memory to store something.
I guess those two errors alone can explain a few undefined behaviors for your program. Given those basic things are totally wrong, I did not analyze the validity of your algorithm itself, because it's being late, and I'm about to go to sleep ;-)

C Arrays and unbroken lists

/edit: thanks for the help so far, however I haven't got any of the solutions to take the sample input and give the sample output. My description isn't the clearest, sorry.
I have an array composed of binary data. What I want to do is determine how long each unbroken segment of 1s or 0s is.
Say I have this data:
0111010001110
In an array binaryArray which I need to translate to:
0100110
stored in nwArray where 0 represents a narrow (less than 3 digits long) and 1 represents wide (>3 digits long). I am not concerned with the binary value but with the length of each component. I'm not sure if that explanation makes sense.
This is what I have; it doesn't work, I can see why, but I can't think of a good solution.
for(x=0;x<1000;x++){
if(binaryArray[x]==binaryArray[x+1]){
count++;
if(count>=3){
nwArray[y]=1;
y++;
count=0;
}
}else{
if(barcodeArray[x]){
nwArray[y]=0;
}
}
}
Does this do it?
int count = 0;
for (x=0; x<1000;x++)
{
if (binaryArray[x] != binaryArray[x+1])
{
if (count < 3)
nwArray[y]=0;
else
nwArray[y]=1;
y++;
count = 0;
}
else
count++;
}
One problem you have is that you compare count with 3 too early. Wait until you see a change in the bitstream. Try a while loop until the bit flips then compare the count.
Modified #MikeW's answer:
int count = 0;
int nwSize = 0;
const int ilast = SIZEOF(binaryArray) - 1;
for (int i = 0; i <= ilast; ++i)
if (i == ilast || binaryArray[i] != binaryArray[i+1]) {
nwArray[nwSize++] = (count > 1); /* true for '1110'; false for '110' */
count = 0;
}
else
++count;
assert(count == 0);

Resources