hi i am writing an arduino program and i must check if a variable divided by 60 gives remainder 0. This variable is increased by 1 each second. I tried to write
if (variable % 60 == 0){
...
}
but it work even if the variable is 3, 6, 9...
my exact code is:
if (millis()/1000 != prevsec){
prevsec = millis()/1000;
if (millis() % 60 == 0){
Serial.print("light");
Serial.println(analogRead(0));
tempC = analogRead(1); //read the value from the sensor
tempC = (5.0 * tempC * 100.0)/1024.0; //convert the analog data to temperature
Serial.print("tempin");
Serial.println((byte)tempC);
}
Serial.println(millis()/1000);
}
Please tell me what i am doing wrong
thanks in advance!
It looks as if you are dividing by 60 a number of milliseconds. You should divide number of seconds.
Related
This question already has answers here:
Check if cyclic (modulo 16) number is larger than another?
(4 answers)
Closed 2 years ago.
I have 2 timestamps represented as milliseconds in the last minute. Imagine there are no synchronization issues between nodes.
The receiver has to distinguish which is the first that was generated message. Unfortunately, after 59 seconds the variables restart, then how to compare these two variables?
Remark: imagine there is a max delay between the timers, i.e. 10 seconds. Otherwise the is no solution to this problem.
My solution is posted below.
Comments in code below:
#include <limits.h>
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
bool millis_in_last_minute_is_valid(int time) {
// represented as milliseconds in the last minute
// after 59 seconds the variables restart
static_assert(INT_MAX > 59999, "Use long and not int to represent numbers greater then 2^16. int has __at least__ 16 bits, it may have 16 bits, in which case INT_MAX is around 32000, which will be lower then 59999 and not able to represent your timestamp");
return 0 <= time && time <= 59999;
}
/**
* #return true if time1 is happened before time2, false otherwise.
*/
bool timestamp_millis_in_last_minute_happened_before(int time1, int time2) {
assert(millis_in_last_minute_is_valid(time1));
assert(millis_in_last_minute_is_valid(time2));
const int diff = abs(time2 - time1);
// imagine there is a max delay between the timers, i.e. 10 seconds
/**
There are 4 cases:
0---------time---------->60000
[---------T1--T2-------->
[---------T2--T1-------->
[-T2-----------------T1->
[-T1-----------------T2->
If the difference is smaller then 10 seconds, it's
one of two first cases, if it's grater then 10 seconds,
it's one of the latter. If the latter, the comparison
needs to just be inverted.
*/
// assert the difference between timestamps is max 10 seconds
assert(
// First two cases
(0 <= diff && diff <= 10000) ||
// Latter two cases
(50000 <= diff && diff < 60000));
return diff <= 10000 ? time1 < time2 : time2 < time1;
}
int main() {
// simple test cases with assert
// 0 is not lower then 0 |T1T2-------> T1 happened with T2
assert(timestamp_millis_in_last_minute_happened_before(0, 0) == 0);
// 1 is not lower then 0 |T2-T1------> T1 happened after T2
assert(timestamp_millis_in_last_minute_happened_before(1, 0) == 0);
// 0 is lower then 1 |T1-T2------> T1 happened before T2
assert(timestamp_millis_in_last_minute_happened_before(0, 1) == 1);
// 59 second happens before 1 |T2------T1-> T1 happened before T2
assert(timestamp_millis_in_last_minute_happened_before(59000, 1) == 1);
// 1 happens before 59 second |T1------T2-> T1 happened before T2
assert(timestamp_millis_in_last_minute_happened_before(1, 59000) == 0);
}
Here is my solution:
int compare_timestamp_millis_in_last_minute(int time1, int time2)
{
if(time1 == time2) return 0;
int millisInLastMinute = get_time_in_millis() % MAXMILLISINMINUTE;
if((time1 - millisInLastMinute % MAXMILLISINMINUTE) > (time2 - millisInLastMinute % MAXMILLISINMINUTE))
return 1;
else
return -1;
}
with MAXMILLISINMINUTE = 65535
Idea behind solution: time1 and time 2 are always less than the time at the moment of comparation. Then subtracting a time that is after will move the time1 and time 2 variable in the left quadrant (both less or equal to 59 s).
Anyone has a different solution?
As I understand this code returns the number of digits entered in the function but I don't understand this operation:
(number /= 10) != 0 at all..I understand that this line
number /= 10
equal to number = number / 10 but why not but why in this function they don't write number / 10 != 0? and what are the differences?
std::size_t numDigits(int number) // function definition.
{ // (This function returns
std::size_t digitsSoFar = 1; // the number of digits
// in its parameter.)
while ((number /= 10) != 0) ++digitsSoFar;
return digitsSoFar;
}
(number /= 10) != 0
This actually has 3 steps. It...
Calculates number / 10
Assigns that value to number
Checks if that value is not equal to 0
So in answer to your question, "why in this function they don't write number / 10 != 0," let's walk through what that does:
Calculates number / 10
Checks if that value is not equal to 0
Can you see the difference between the two?
If you're still not sure why this matters, put an output statement in the while loop that'll show number and digitsSoFar and try to run that function both the way it's written and then with your proposed version.
I recently ordered a DHT22 temperature and humidity sensor to play around with as well as some arduino nanos that I am still waiting on, and I was reading up on a few tutorials and things I am going to do with them when I get them and was reading through how to use the DHT22 which was pretty simple, and after reading the data sheet was interested in how they iterate through the 40 bits of data as I have never played around with bytes in code before so looked up the library for it which is here https://github.com/markruys/arduino-DHT.
Datasheet for DHT22 is here https://cdn-shop.adafruit.com/datasheets/Digital+humidity+and+temperature+sensor+AM2302.pdf
This is the main block of code that loops through the bits.
This is what I think is happening; you have an 8 bit int of i that starts at -3 because it uses 3 bits to start communicating with the sensor. i < 2 * 40 keeps i below 2 but iterates through 40 times (this is a stab in the dark, i haven't seen it before).
Next is the bit I'm not quite understanding at all, the while loop, where if the pin is high - 1 and is == (i(i being 0) & 1) then the while loop will be LOW, or if i is 1 then the loop will be high. Which then flows into the if statement where if ( i >= 0 && (i & 1)), but won't i eventually always be 1? If not what is modifying i? From what I have looked at you don't want to move the bits when the signal is LOW?
I can see what the rest of the code is doing I'm just not understanding it, the first if statement moves the bits i data left through every loop and if the signal is high for > 30 micro secs then the bit is 1 and a 1 is added to data.
// We're going to read 83 edges:
// - First a FALLING, RISING, and FALLING edge for the start bit
// - Then 40 bits: RISING and then a FALLING edge per bit
// To keep our code simple, we accept any HIGH or LOW reading if it's max 85 usecs long
uint16_t rawHumidity = 0;
uint16_t rawTemperature = 0;
uint16_t data = 0;
for ( int8_t i = -3 ; i < 2 * 40; i++ ) {
byte age;
startTime = micros();
do {
age = (unsigned long)(micros() - startTime);
if ( age > 90 ) {
error = ERROR_TIMEOUT;
return;
}
} while ( digitalRead(pin) == (i & 1) ? HIGH : LOW );
if ( i >= 0 && (i & 1) ) {
// Now we are being fed our 40 bits
data <<= 1;
// A zero max 30 usecs, a one at least 68 usecs.
if ( age > 30 ) {
data |= 1; // we got a one
}
}
switch ( i ) {
case 31:
rawHumidity = data;
break;
case 63:
rawTemperature = data;
data = 0;
break;
}
}
// Verify checksum
if ( (byte)(((byte)rawHumidity) + (rawHumidity >> 8) + ((byte)rawTemperature) + (rawTemperature >> 8)) != data ) {
error = ERROR_CHECKSUM;
return;
}
This is what I think is happening; you have an 8 bit int of i that starts at -3 because
it uses 3 bits to start communicating with the sensor. i < 2 * 40 keeps i below 2 but
iterates through 40 times (this is a stab in the dark, i haven't seen it before)
https://en.cppreference.com/w/cpp/language/operator_precedence
* (as the multiplication operator) has higher precedence than < (as less-than), so the terms are grouped such that * is resolved first.
So (i < 2 * 40) gets resolved (i < (2 * 40)). It's equivalent to (i < 80).
Next is the bit I'm not quite understanding at all, the while loop, where if the pin
is high - 1 and is == (i(i being 0) & 1) then the while loop will be LOW, or if i is
1 then the loop will be high.
do {
...
}
while ( digitalRead(pin) == (i & 1) ? HIGH : LOW );
Here, == has the higher precedence, so (digitalRead(pin) == (i & 1) is resolved first. ie, true when either digitalRead(pin) is 0 and i is even, digitalRead(pin) is 1 and i is odd. [since (i & 1) effectively tests the lowest bit]
Then the ternary subexpression is resolved, returning HIGH if true and LOW if false.
Have to run, hopefully that gets you there.
// We're going to read 83 edges:
// - First a FALLING, RISING, and FALLING edge for the start bit
// - Then 40 bits: RISING and then a FALLING edge per bit
The data bits shift left when the 'while' loop breaks: that happens when
the conditional's ternary operator result (HIGH or LOW) evaluates false. It's somewhat unclear exactly when that should occur since we lack definitions for HIGH and LOW.
However, since:
all-caps identifiers generally indicate that the identifier represents a macro,
HIGH and LOW having strictly constant truth value would make having the ternary expression in there at all totally pointless (if true then true else false??),
something in all this supposedly distinguishes rising-edge values from falling edges,
there's pretty much no other sensible place for that to happen (unless the pin read function does it internally and the comments discussion is just watercooler stuff)
...we should probably assume they each expand to an expression of some sort, and the result of THAT determines whether the loop should stop.
So, most likely, data <<= 1; occurs when:
digitalRead(pin) is high and *~something~*
digitalRead(pin) is low and *~something else~*
From what I can see, it would make the most sense if ~something~ and ~something else~ depend on the value of age.
I please check this problem I'm creating a Time Base app but I'm having problem getting to work around the modulus oper (%) I want the remainder of 50%60 which I'm expecting to output 10 but it just give me the Lhvalues instead i.e 50. How do I go about it.
Here is a part review of the code.
void setM(int m){
if ((m+min)>59){
hour+=((min+m)/60);
min=0;
min=(min+m)%60;
}
else min+=m;
}
In the code m is passed in as 50 and min is passed in as 10
How do I get the output to be 10 for min in this equation min=(min+m)%60; without reversing the equation i.e
60%(min+m)
in C++ expression a % b returns remainder of division of a by b (if they are positive. For negative numbers sign of result is implementation defined).
you should do : 60 % 50 if you want to divide by 50
Or, if you want to get mins, i think you don't need to make min=0.
When you do 50 % 60, you get a remiainder of 50 since 50 cannot be divided by 60.
To get around this error, you can try doing do something like 70 % 60 to get the correct value as a result, since you do not want to use 60 % 50
This would follow the following logic:
Find the difference between 60 and min + m after min is set to zero if min + mis less than 60. Store it in a variable var initially set to zero.
check if the result is negative; if it is, then set it to positive by multiplying it by -1
When you do the operation, do min = ((min + m) + var) % 60; instead.
***Note: As I am unfamiliar with a Time Base App and what its purpose is, this solution may or may not be required, hence please inform me in the comments before downvoting if I there is anything wrong with my answer. Thanks!
It looks like you are trying to convert an integral number of minutes to an hour/minute pair. That would look more like this instead:
void setM(int m)
{
hour = m / 60;
min = m % 60;
}
If you are trying to add an integral number of minutes to an existing hour/minute pair, it would look more like this:
void addM(int m)
{
int value = (hour * 60) + min;
value += m;
hour = value / 60;
min = value % 60;
}
Or
void addM(int m)
{
setM(((hour * 60) + min) + m);
}
I am trying to make a simple Arduino code for when a photocell reading is less than 900, it will add 1 to the CurrentNumber and display it on a 4 digit 7 segment display. The problem is that it wont stop adding one even though it's reading more than 1000.
void loop() {
photocellReading = analogRead(photocellPin);
Serial.print("Analog reading = ");
Serial.println(photocellReading); // the raw analog reading
photocellReading = 1023 - photocellReading;
if(photocellReading << 10){
CurrentNumber = CurrentNumber + 1;
}
displayNumber(CurrentNumber);
}
Your problem is in your if condition:
if(photocellReading << 10){
CurrentNumber = CurrentNumber + 1;
}
What you're essentially doing he is: shifting the bits of photocellReading to the left by 10 (which is equivalent to multiplying by 2^10 aka 1024). Most likely this means the only time this is ever going to be false is if the value of photocellReading was 0 to start with. (I say most likely because it depends on if the bits loop back around or not, but this is not entirely relevant).
tl;dr your code is conceptually equivalent to:
if((photocellReading * 1024) != 0){
CurrentNumber = CurrentNumber + 1;
}
What I'm guessing you wanted to do (considering you subtracted 1023, which coincidentally is 1024 - 1) is:
if(photocellReading < 1024){ // again 1024 == 2^10
CurrentNumber = CurrentNumber + 1;
}