text:
7 segment displays arduino mega 2560
I'm trying to use an Arduino Mega 2560 to use 7-segment displays, 6 displays... I use 3 CD4543B to pilot the 6 displays.
It works very well for 4 displays as you can see in this video.
But when I want to use the same circuit for 5 or 6 displays, there is some bug as you can see on this video for 5 displays.
Here is the code that works fine for 4 displays:
//définition des broches du premier décodeur
const int bit_A=8;
const int bit_B=9;
const int bit_C=10;
const int bit_D=11;
//définition du brochage du deuxieme decodeur
const int bit_E=22;
const int bit_F=24;
const int bit_G=26;
const int bit_H=28;
//définition du brochage du 3ième décodeur
const int bit_I=40;
const int bit_J=42;
const int bit_K=44;
const int bit_L=46;
//définition des broches des transistors

const int alim_millier=3;
const int alim_centaine=4;
const int alim_dizaine=5;
const int alim_unite=6;

void setup() {
  //les broches sont toutes des sorties
  pinMode(bit_A,OUTPUT);
  pinMode(bit_B,OUTPUT);
  pinMode(bit_C,OUTPUT);
  pinMode(bit_D,OUTPUT);
  pinMode(bit_E,OUTPUT);
  pinMode(bit_F,OUTPUT);
  pinMode(bit_G,OUTPUT);
  pinMode(bit_H,OUTPUT);
  pinMode(bit_I,OUTPUT);
  pinMode(bit_J,OUTPUT);
  pinMode(bit_K,OUTPUT);
  pinMode(bit_L,OUTPUT);
  pinMode(alim_millier,OUTPUT);
  pinMode(alim_centaine,OUTPUT);
  pinMode(alim_dizaine,OUTPUT);
  pinMode(alim_unite,OUTPUT);
  //les broches sont toutes mises à l'état bas
  digitalWrite(bit_A,LOW);
  digitalWrite(bit_B,LOW);
  digitalWrite(bit_C,LOW);
  digitalWrite(bit_D,LOW);
  digitalWrite(bit_E,LOW);
  digitalWrite(bit_F,LOW);
  digitalWrite(bit_G,LOW);
  digitalWrite(bit_H,LOW);
  digitalWrite(bit_I,LOW);
  digitalWrite(bit_J,LOW);
  digitalWrite(bit_K,LOW);
  digitalWrite(bit_L,LOW);
  digitalWrite(alim_millier,LOW);
  digitalWrite(alim_centaine,LOW);
  digitalWrite(alim_dizaine,LOW);
  digitalWrite(alim_unite,LOW);
}

void loop() {
  //fonction principale
  for(int i=0; i<10000; i++) {
    //boucle qui permet de compter de0 à9999(=10000 valeurs)
    afficher_nombre(i);//appelde la fonction affichage avec envoi du nombre à afficher
  }
}

//fonction permettant d'afficherun nombre sur quatre afficheurs
void afficher_nombre(int nombre) {
  long temps;//variable utilisée poursavoir le temps écoulé
  int unite=0,dizaine=0,centaine=0, millier=0;//variable pour chaque afficheur
  millier=nombre/1000;//on récupère les milliers
  centaine=(nombre-1000*millier)/100;//on récupère les centaines
  dizaine=(nombre-(centaine*100)-(millier*1000))/10;//on récupère les dizaines
  unite=nombre-(millier*1000)-(centaine*100)-(dizaine*10);//on récupère les unités
  temps=millis();//on récupère le temps courant
  //tant qu'on a pas affiché ce chiffre pendant au moins 500 milliseconde
  //permet donc de pouvoir lire le nombre affiché
  while((millis()-temps)<500) {
    //on affiche le nombre
    //d'abord les milliers pendant 5ms
    digitalWrite(alim_millier,HIGH);
    afficher_CD(millier);//on appelle la fonction qui permet d'afficher le chiffre millier
    digitalWrite(alim_centaine,LOW);
    digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
    digitalWrite(alim_unite,LOW);//le transistor est bloqué
    delay(5);
    //d'abord les centaines pendant 5ms
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,HIGH);//le transistor de l'afficheur des centaines est saturé, donc l'afficheur est allumé
    afficher_CM(centaine);//on appelle la fonction qui permet d'afficher le chiffre centaine
    digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
    digitalWrite(alim_unite,LOW);//le transistor est bloqué
    delay(5);
    //ensuite les dizaines pendant 5 ms
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,LOW);// transistor est bloqué
    digitalWrite(alim_dizaine,HIGH);//transistor saturé
    afficher_CM(dizaine);
    digitalWrite(alim_unite,LOW);//transistor bloqué
    delay(5);
    //on affiche les unités 5 ms
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,LOW);//transistor bloqué
    digitalWrite(alim_dizaine,LOW);//transistor bloqué
    digitalWrite(alim_unite,HIGH);//transistor saturé
    afficher_UD(unite);
    delay(5);
  }
}

//fonction écrivant sur les premiers afficheurs
void afficher_UD(int chiffre) {
  digitalWrite(bit_A,LOW);
  digitalWrite(bit_B,LOW);
  digitalWrite(bit_C,LOW);
  digitalWrite(bit_D,LOW);
  if(chiffre>=8) {
    digitalWrite(bit_D,HIGH);
    chiffre=chiffre-8;
  }
  if(chiffre>=4) {
    digitalWrite(bit_C,HIGH);
    chiffre=chiffre-4;
  }
  if(chiffre>=2) {
    digitalWrite(bit_B,HIGH);
    chiffre=chiffre-2;
  }
  if(chiffre>=1) {
    digitalWrite(bit_A,HIGH);
    chiffre=chiffre-1;
  }
}

//fonction écrivant sur le second afficheur
void afficher_CM(int chiffre) {
  digitalWrite(bit_E,LOW);
  digitalWrite(bit_F,LOW);
  digitalWrite(bit_G,LOW);
  digitalWrite(bit_H,LOW);
  if(chiffre>=8) {
    digitalWrite(bit_H,HIGH);
    chiffre=chiffre-8;
  }
  if(chiffre>=4) {
    digitalWrite(bit_G,HIGH);
    chiffre=chiffre-4;
  }
  if(chiffre>=2) {
    digitalWrite(bit_F,HIGH);
    chiffre=chiffre-2;
  }
  if(chiffre>=1) {
    digitalWrite(bit_E,HIGH);
    chiffre=chiffre-1;
  }
}

void afficher_CD(int chiffre) {
  digitalWrite(bit_I,LOW);
  digitalWrite(bit_J,LOW);
  digitalWrite(bit_K,LOW);
  digitalWrite(bit_L,LOW);
  if(chiffre>=8) {
    digitalWrite(bit_L,HIGH);
    chiffre=chiffre-8;
  }
  if(chiffre>=4) {
    digitalWrite(bit_K,HIGH);
    chiffre=chiffre-4;
  }
  if(chiffre>=2) {
    digitalWrite(bit_J,HIGH);
    chiffre=chiffre-2;
  }
  if(chiffre>=1) {
    digitalWrite(bit_I,HIGH);
    chiffre=chiffre-1;
  }
}

And here the code for 5 displays with "bugs" :
//définition des broches du premier décodeur
const int bit_A=8;
const int bit_B=9;
const int bit_C=10;
const int bit_D=11;
//définition du brochage du deuxieme decodeur
const int bit_E=22;
const int bit_F=24;
const int bit_G=26;
const int bit_H=28;
//définition du brochage du 3ième décodeur
const int bit_I=40;
const int bit_J=42;
const int bit_K=44;
const int bit_L=46;
//définition des broches des transistors
const int alim_dm= 3;
const int alim_millier=4;
const int alim_centaine=5;
const int alim_dizaine=6;
const int alim_unite=7;
void setup() {
  //les broches sont toutes des sorties
  pinMode(bit_A,OUTPUT);
  pinMode(bit_B,OUTPUT);
  pinMode(bit_C,OUTPUT);
  pinMode(bit_D,OUTPUT);
  pinMode(bit_E,OUTPUT);
  pinMode(bit_F,OUTPUT);
  pinMode(bit_G,OUTPUT);
  pinMode(bit_H,OUTPUT);
  pinMode(bit_I,OUTPUT);
  pinMode(bit_J,OUTPUT);
  pinMode(bit_K,OUTPUT);
  pinMode(bit_L,OUTPUT);
  pinMode(alim_dm,OUTPUT);
  pinMode(alim_millier,OUTPUT);
  pinMode(alim_centaine,OUTPUT);
  pinMode(alim_dizaine,OUTPUT);
  pinMode(alim_unite,OUTPUT);
  //les broches sont toutes mises à l'état bas
  digitalWrite(bit_A,LOW);
  digitalWrite(bit_B,LOW);
  digitalWrite(bit_C,LOW);
  digitalWrite(bit_D,LOW);
  digitalWrite(bit_E,LOW);
  digitalWrite(bit_F,LOW);
  digitalWrite(bit_G,LOW);
  digitalWrite(bit_H,LOW);
  digitalWrite(bit_I,LOW);
  digitalWrite(bit_J,LOW);
  digitalWrite(bit_K,LOW);
  digitalWrite(bit_L,LOW);
  digitalWrite(alim_dm,LOW);
  digitalWrite(alim_millier,LOW);
  digitalWrite(alim_centaine,LOW);
  digitalWrite(alim_dizaine,LOW);
  digitalWrite(alim_unite,LOW);
}

void loop() {
  //fonction principale
  for(int i=0;i<100000;i++)//boucle qui permet de compter de0 à 99999(=100000 valeurs) {
    afficher_nombre(i);//appelde la fonction affichage avec envoi du nombre à afficher
  }
}

//fonction permettant d'afficherun nombre sur quatre afficheurs
void afficher_nombre(int nombre) {
  long temps;//variable utilisée poursavoir le temps écoulé
  int unite=0,dizaine=0,centaine=0, millier=0, dm=0;//variable pour chaque afficheur
  dm=nombre/10000;//on récupère les dm
  millier=(nombre-(10000*dm))/1000;//on récupère les milliers
  centaine=(nombre-1000*millier)-(10000+dm)/100;//on récupère les centaines
  dizaine=(nombre-(centaine*100)-(millier*1000)-(dm*10000))/10;//on récupère les dizaines
  unite=nombre-(dm*10000)-(millier*1000)-(centaine*100)-(dizaine*10);//on récupère les unités

  temps=millis();//on récupère le temps courant
  //tant qu'on a pas affiché ce chiffre pendant au moins 500 milliseconde
  //permet donc de pouvoir lire le nombre affiché
  while((millis()-temps)<500) {
    //on affiche le nombre
    //d'abord les dms pendant 5ms
    digitalWrite(alim_dm,HIGH);
    afficher_CD(dm);//on appelle la fonction qui permet d'afficher le chiffre dm
    digitalWrite(alim_millier,LOW);//le transistor bloqué
    digitalWrite(alim_centaine,LOW);//le transistor est bloqué
    digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
    digitalWrite(alim_unite,LOW);//le transistor bloqué
    delay(10);
    //d'abord les millier pendant 5ms
    digitalWrite(alim_dm,LOW);
    digitalWrite(alim_millier,HIGH);//le transistor de l'afficheur des centaines est saturé, donc l'afficheur est allumé
    afficher_CM(millier);//on appelle la fonction qui permet d'afficher le chiffre centaine
    digitalWrite(alim_centaine,LOW);//le transistor est bloqué
    digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
    digitalWrite(alim_unite,LOW);//le transistor bloqué
    delay(10);
    //ensuite les centaine pendant 5 ms
    digitalWrite(alim_dm,LOW);
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,HIGH);// transistor est bloqué
    afficher_CM(centaine);
    digitalWrite(alim_dizaine,LOW);//transistor saturé
    digitalWrite(alim_unite,LOW);//transistor bloqué
    delay(10);
    //on affiche les dizaines 5 ms
    digitalWrite(alim_dm,LOW);
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,LOW);//transistor bloqué
    digitalWrite(alim_dizaine,HIGH);//transistor bloqué
    afficher_UD(dizaine);
    digitalWrite(alim_unite,LOW);//transistor saturé
    delay(10);
    //on affiche les unités
    digitalWrite(alim_dm,LOW);
    digitalWrite(alim_millier,LOW);
    digitalWrite(alim_centaine,LOW);//transistor bloqué
    digitalWrite(alim_dizaine,LOW);//transistor bloqué
    digitalWrite(alim_unite,HIGH);//transistor saturé
    afficher_UD(unite);
    delay(10);
  }
}

//fonction écrivant sur les premiers afficheurs
void afficher_UD(int chiffre) {
  digitalWrite(bit_A,LOW);
  digitalWrite(bit_B,LOW);
  digitalWrite(bit_C,LOW);
  digitalWrite(bit_D,LOW);
  if(chiffre>=8) {
    digitalWrite(bit_D,HIGH);
    chiffre=chiffre-8;
  }
  if(chiffre>=4) {
    digitalWrite(bit_C,HIGH);
    chiffre=chiffre-4;
  }
  if(chiffre>=2) {
    digitalWrite(bit_B,HIGH);
    chiffre=chiffre-2;
  }
  if(chiffre>=1) {
    digitalWrite(bit_A,HIGH);
    chiffre=chiffre-1;
  }
}

//fonction écrivant sur le second afficheur
void afficher_CM(int chiffre) {
  digitalWrite(bit_E,LOW);
  digitalWrite(bit_F,LOW);
  digitalWrite(bit_G,LOW);
  digitalWrite(bit_H,LOW);
  if(chiffre>=8) {
    digitalWrite(bit_H,HIGH);
    chiffre=chiffre-8;
  }
  if(chiffre>=4) {
    digitalWrite(bit_G,HIGH);
    chiffre=chiffre-4;
  }
  if(chiffre>=2) {
    digitalWrite(bit_F,HIGH);
    chiffre=chiffre-2;
  }
  if(chiffre>=1) {
    digitalWrite(bit_E,HIGH);
    chiffre=chiffre-1;
  }
}

void afficher_CD(int chiffre) {
  digitalWrite(bit_I,LOW);
  digitalWrite(bit_J,LOW);
  digitalWrite(bit_K,LOW);
  digitalWrite(bit_L,LOW);
  if(chiffre>=8) {
    digitalWrite(bit_L,HIGH);
    chiffre=chiffre-8;
  }
  if(chiffre>=4) {
    digitalWrite(bit_K,HIGH);
    chiffre=chiffre-4;
  }
  if(chiffre>=2) {
    digitalWrite(bit_J,HIGH);
    chiffre=chiffre-2;
  }
  if(chiffre>=1) {
    digitalWrite(bit_I,HIGH);
    chiffre=chiffre-1;
  }
}
//Fin du programme

I've been trying for weeks to understand the problem. All displays work fine, and if I adapt the code for 4 displays and try to use any 4 of the 6 displays it works fine (I have tried a combination such as displays: 1, 2, 3, 4 or 2, 3, 4, 5 or 3, 4, 5, 6 or 1, 2, 5, 6, everything works).
Thanks to a conversation on the Arduino forum, I also tried this code for 5 displays but I still have the same problem:
//Da
const int bit_A=8;
const int bit_B=9;
const int bit_C=10;
const int bit_D=11;
//Db
const int bit_E=22;
const int bit_F=24;
const int bit_G=26;
const int bit_H=28;
//Dc
const int bit_I=40;
const int bit_J=42;
const int bit_K=44;
const int bit_L=46;
// transistors
const int alim_dizainemillier= 3;
const int alim_millier=4;
const int alim_centaine=5;
const int alim_dizaine=6;
const int alim_unite=7;
void setup() {
  pinMode(bit_A,OUTPUT);
  pinMode(bit_B,OUTPUT);
  pinMode(bit_C,OUTPUT);
  pinMode(bit_D,OUTPUT);
  pinMode(bit_E,OUTPUT);
  pinMode(bit_F,OUTPUT);
  pinMode(bit_G,OUTPUT);
  pinMode(bit_H,OUTPUT);
  pinMode(bit_I,OUTPUT);
  pinMode(bit_J,OUTPUT);
  pinMode(bit_K,OUTPUT);
  pinMode(bit_L,OUTPUT);
  pinMode(alim_dizainemillier,OUTPUT);
  pinMode(alim_millier,OUTPUT);
  pinMode(alim_centaine,OUTPUT);
  pinMode(alim_dizaine,OUTPUT);
  pinMode(alim_unite,OUTPUT);
  digitalWrite(bit_A,LOW);
  digitalWrite(bit_B,LOW);
  digitalWrite(bit_C,LOW);
  digitalWrite(bit_D,LOW);
  digitalWrite(bit_E,LOW);
  digitalWrite(bit_F,LOW);
  digitalWrite(bit_G,LOW);
  digitalWrite(bit_H,LOW);
  digitalWrite(bit_I,LOW);
  digitalWrite(bit_J,LOW);
  digitalWrite(bit_K,LOW);
  digitalWrite(bit_L,LOW);
  digitalWrite(alim_dizainemillier,LOW);
  digitalWrite(alim_millier,LOW);
  digitalWrite(alim_centaine,LOW);
  digitalWrite(alim_dizaine,LOW);
  digitalWrite(alim_unite,LOW);
}

void loop() {
  for(int i=0;i<100000;i++) {
    afficher_nombre(i);
    delay(5);
  }
}

void afficher_nombre(int nombre) {
  long temps;
  int unite=0,dizaine=0,centaine=0, millier=0, dizainemillier=0;
  dizainemillier=nombre/10000;
  millier=(nombre-(10000*dizainemillier))/1000;
  centaine=(nombre-(1000*millier)-(10000*dizainemillier))/100;
  dizaine=(nombre-(centaine*100)-(millier*1000)-(dizainemillier*10000))/10;
  unite=nombre-(dizainemillier*10000)-(millier*1000)-(centaine*100)-(dizaine*10);
  temps=millis();
  while((millis()-temps)<500){
    afficher_CD(dizainemillier);
    digitalWrite(alim_dizainemillier, HIGH);
    delay(5);
    digitalWrite(alim_dizainemillier, LOW);
    afficher_CM(millier);
    digitalWrite(alim_millier, HIGH);
    delay(5);
    digitalWrite(alim_millier, LOW);
    afficher_CM(centaine);
    digitalWrite(alim_centaine, HIGH);
    delay(5);
    digitalWrite(alim_centaine, LOW);
    afficher_UD(dizaine);
    digitalWrite(alim_dizaine, HIGH);
    delay(5);
    digitalWrite(alim_dizaine, LOW);
    afficher_UD(unite);
    digitalWrite(alim_unite, HIGH);
    delay(5);
    digitalWrite(alim_unite, LOW);
  }
}

void afficher_UD(int chiffre) {
  digitalWrite(bit_A,chiffre & 1);
  digitalWrite(bit_B,chiffre & 2);
  digitalWrite(bit_C,chiffre & 4);
  digitalWrite(bit_D,chiffre & 8);
}

void afficher_CM(int chiffre) {
  digitalWrite(bit_E,chiffre & 1);
  digitalWrite(bit_F,chiffre & 2);
  digitalWrite(bit_G,chiffre & 4);
  digitalWrite(bit_H,chiffre & 8);
}

void afficher_CD(int chiffre) {
  digitalWrite(bit_I,chiffre & 1);
  digitalWrite(bit_J,chiffre & 2);
  digitalWrite(bit_K,chiffre & 4);
  digitalWrite(bit_L,chiffre & 8);
}

Any clue is very welcome! Thanks!

I think it's because I use int and I should use long to avoid overflow... for the number I want to display:
void loop()
{
 for(int i=0;i<100000;i++)
 {
   afficher_nombre(i);
   delay(5);
 }
}

should be :
void loop()
{
 for(long i=0;i<100000;i++)
 {
   afficher_nombre(i);
   delay(5);
 }
}

And also a parentheses problem solved thanks to cattledog on this forum

on Arduino int is 16-bit (2-byte) value. This yields a range of -32,768 to 32,767 while long is 32 bits (4 bytes), from -2,147,483,648 to 2,147,483,647

exactly :) ! I'm use to code for 64bits or 32bits on computer, and forgot that arduino is 16bits....

Here is the code that works fine for 4 displays:

both code pieces suffer from the use of "delay()".
here is what I used - https://dannyelectronics.wordpress.com/2017/06/30/a-more-flexible-driver-for-7-segment-leds/
it is written so the leds can be driven by individual pins so porting to  arduino requires no change to the source code - just a few macros to remap the IO operations.
also running it from a timer isr is the (only) way to go.
edit: here is to show how the code above gets to work here. I expanded it to cover 8 digits but only the first 6 digits effective. three macros are all it takes to repurpose it for arduino.
displaying a fixed "123456".

all the user code does is to dump the content to be displayed into the display buffer and the display routine, led_display() takes care of the rest.


text:
Why can't I define the constant A0 (some pin) to something?
What I'm doing wrong or why is it not working:
#define Uin A0;

void setup() {
}

void loop() {
  analogRead(Uin);
}

Results in a Error (expected ')' before ; token.
I thought #define just exists as a place holder.

Because you have a ; at the end of your #define.
#define Uin A0;
analogRead(Uin);

becomes:
analogRead(A0;);

The Arduino website mentions this in their reference. For more in-depth detail about the C pre-processor you can read the (rather large) manual here.

That's it. Thank you.
Could you please link to the reference. (It is also answered there - I'm sorry) [In 5 min I can accept the answer]
link

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
How to code multiple conditions inside if statement?
I have a system that checks the value of a moisture sensor and will also check the time
if (t.hour == 7 && t.min == 00 && moistureOneSensorValue >= 700) {
  RelayOne();
  RelayTwo();
}

When moistureOneSensorValue is greater than or equal to 700 it means the soil is DRY, so when all conditions inside the if statement are true the relayOne and relayTwo functions will be called.
My problem is that when moistureOneSensorValue is still moist the above if statement will result in false and the relayOne and relayTwo functions will not be called. I want Arduino to execute and call the relayOne and relayTwo functions and disregard the time. I use time so that the system will only call the relayOne and relayTwo functions in the morning at exactly 7 AM every day, but it needs to check/make sure that the soil is DRY...
Example
First thing in the morning the system will check the time and sensor value; if the if statement results in false the system will keep monitoring and try the if statement until the soil is DRY. But I think when that happens it will be over 7 AM.
Sorry for the messy explanation.

I think where is says "s still moist" in your question you meant to say "s still dry".

yeah , when it still dry the if statement will result in true ..

You first have to sort out in your head what you want the Arduino to do. At this point it just seems you do not know what you want.

I'm not sure how quickly you soil could get dry, but I suspect what you want to do is to periodically check the dryness throughout the day. Say like every two hours:
// Check every 2 hrs (when hr is even)
if ( t.hour % 2 == 0 && moistureOneSensorValue >= 700 ) {...}

You could also bound it to only during the day time:
if ( t.hour >= 7 // after 7a
  && t.hour <= 19 // before 7p
  && t.hour % 2 == 1 // every 2 hrs (when hr is odd)
  && moistureOneSensorValue >= 700 // soil is dry
) {...}

If the event is to be time independent then it follows you can not check the time.  If the event is to be both time independent and dependent then you need to add the code to handle the logic.
Consider checking if it is between 7am and, say, 7pm.  If true then test if the moisture detector is dry.  If true then close (watering) relays.
(This is only a code example and has not been tested.)
if(t.hour >= 7 && t.hour <= 19)
{
  while(moistureOneSensorValue >= 700)
  {
   RelayOne();
   RelayTwo();
  }
}

Consider adding a state machine to mitigate possible problems by monitoring minimum times between events and maximum times of events.  For example, do not water more than once per 5 minutes.  Do not water more than 30 seconds at a time.  Do not water more then a total of 1 minute per hour.  Do not water more than 5 minutes per 24 hours.

So i just code like this , if (t.hour == 7 && t.min == 00 && ) {   while(moistureOneSensorValue >= 700) RelayOne();   RelayTwo(); }

An untested code example has been added to the answer.

what if the soil is quickly dry ? so it will water the plant more than the allowed watering a day

Those were examples times and constraints.  If I were to make an automated watering system I would be very very worried about water damage should something go wrong.  Maybe you will have a fix amount of water such as a watering jug as your water source so as to avoid the problem.  Maybe you will only do this out side where watering problems will do less damage.  Maybe you need to enhance your software such that it will mitigate over or under watering problems.  Maybe you are watering a 10 ounce potted plant & need to keep the times short.  Maybe you are watering a plot of tomato vines.

I'm just saying, there are a lot of open ended problems for such a project.  Software can offer the flexibility to solve most of them.  But you need to think each and every problem through.

I'm connecting/interfacing  my arduino with java .. and use solenoid valve and water flow sensor to control the water

As of now this is the last problem i'm facing if (t.hour == 7 && t.min == 00 && ) { while(moistureOneSensorValue >= 700) RelayOne(); RelayTwo(); }

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
NRF24L01+ Issues antenna
I have 2x NRF24L01+ communicating but they are unreliable. It doesn't matter if they are right night to each other or 100ft away. For some odd reason when I place my hand on the antenna it work perfectly. Why would this be?
I have one set up to send and one to receive. All I am sending from one to the other is a 3 digit number to turn on a relay.

Are they the modules with the power amp and SMA antenna, or the ones without the amplifier and PCB track or ceramic antenna?

And how well do they work if they are 20' away from each other? Too close and it will distort the signal. Too distant and the signal will be too weak.

Yes they are SMA. Here is what I bought link . About 30' away was my test and still the same issue. I found when I remove the antenna is works much better.

Those ones don't work well when too close together. The signal is too strong and distorts. You may be attenuating it with your hand making it work better. It should be good over 100' though.

I found a solution. As the signals where too close I found where I could tone down the signal strength using:
   radio.setPALevel(RF24_PA_MIN);

Because I didn't want to loose long range capabilities too I send my packet out 4 times at this lower signal and then increase the strength back to max to send out another 4 packets. This way my close range and far range relay will receive the signal.


text:
How to make 4 digits 7 segments common cathode thermometer
I'm new to Arduino and I have this problem: The common cathode 4 digits 7-segments keep on blinking even the code and my connection is correct (in my opition). I have used an LM35 IC to read the temperature
 I've just followed this pattern:
and I used this code:
const int digitPins[4] = {5,4,3,2}; //4 common CATHODE pins of the display (inverted the pins order)
const int clockPin = 7;    //74HC595 Pin 11
const int latchPin = 8;    //74HC595 Pin 12
const int dataPin = 12;     //74HC595 Pin 14
const int tempPin = A0;     //temperature sensor pin
const byte digit[10] =      //seven segment digits in bits
{
  B00111111, //0
  B00000110, //1
  B01011011, //2
  B01001111, //3
  B01100110, //4
  B01101101, //5
  B01111101, //6
  B00000111, //7
  B01111111, //8
  B01101111  //9
};
int digitBuffer[4] = {0};
int digitScan = 0;
float tempC; //Deleted kelvin and farenheit

void setup(){
  for(int i=0;i<4;i++)
  {
    pinMode(digitPins[i],OUTPUT);
  }
  pinMode(tempPin, INPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(tempPin, INPUT);
  //Serial.begin(9600);
}

//writes the temperature on display
void updateDisp(){

  for(byte j=0; j<4; j++) {digitalWrite(digitPins[j], HIGH);} // Turns the display off. Changed to HIGH
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
  digitalWrite(latchPin, HIGH);

  delayMicroseconds(2);

  digitalWrite(digitPins[digitScan], LOW); //Changed to LOW for turning the leds on.

  digitalWrite(latchPin, LOW);
  if(digitScan==2)
    shiftOut(dataPin, clockPin, MSBFIRST, (digit[digitBuffer[digitScan]] | B10000000)); //print the decimal point on the 3rd digit
  else
    shiftOut(dataPin, clockPin, MSBFIRST, digit[digitBuffer[digitScan]]);

  digitalWrite(latchPin, HIGH);

  digitScan++;
  if(digitScan>3) digitScan=0;
}

void loop(){
  tempC = analogRead(tempPin)*0.00488;  //multiplied for this conversion constant
  tempC = tempC*10000;
  digitBuffer[3] = int(tempC)/1000;
  digitBuffer[2] = (int(tempC)%1000)/100;
  digitBuffer[1] = (int(tempC)%100)/10;
  digitBuffer[0] = (int(tempC)%100)%10;

  if (digitBuffer[0]>=5) {
    digitBuffer[0] = 5;
  }
  else {
    digitBuffer[0] = 0;
  }

  delay(5);
  updateDisp();
}

Who designed that circuit?

By "blinking" do you mean the display is showing the right thing but it's just flickering, or it's just flashing random stuff on and off?

it just flashing random stuff sir Majenko.

I just saw it on a comment in this link https://www.instructables.com/id/Temperature-Displayed-on-4-Digit-7-segment-common/

Ah right, well maybe using the original circuit from the instructable may be better - that one is using its resistors completely wrong, and if something so basic is wrong then I can't vouch for the rest of the circuit being right...

i cannot use the original circuit sir because i'm just using 12 pins 4 digits 7 segments while he is using 16 pins sir

Looks like he's using a 12 pin display to me - even the pin layout is the same. Follow the wires and note the order. Ignore the fact he is showing it with individual displays - that'll just be because he didn't have the real one in Fritzing.

Also, is there any reason you want to use the shift register? The Uno has enough pins o drive the display directly without need of a shift register, and you'll get a much smoother display (no delays while it shifts). You could even drive it with a timer interrupt to make it even smoother.

because sir later i will need the other pins to use fire sensor,light sensor,buzzer, tilt and LEDs

Maybe removing the 5ms delay from your loop may improve things a little.

A better way is to have the resistors on the anode side of the LED instead as this will help balance any uneven voltage drop of the diodes.

First thing to check is that you have the IC and the 7-segment display module connected the correct way around. As a reference, the green wire is attached to Pin 14 of the 74HC595 IC, so pin 1 would be the top right pin. The 7-segment display should have the the dot points towards the bottom.
Check that you have a common cathode display. You can do this by applying a voltage, through a 220 ohm resistor, verifying that it lights up when positive is on pins A-G and Gnd connected to the common cathode pin.
Check the code by removing the temperature section of the code and just writing '0's to all 4 digits. In fact it would be worth testing the digits one by one. The below code should do just that (unverified):
const int clockPin = 7;    //74HC595 Pin 11
const int latchPin = 8;    //74HC595 Pin 12
const int dataPin = 12;    //74HC595 Pin 14
const int digitPins[4] = {5,4,3,2};

void setup(){
  for(int i=0;i<4;i++)
  {
    pinMode(digitPins[i],OUTPUT);
    digitalWrite(digitPins[i], HIGH);
  }
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  for(int i=0;i<4;i++)
  {
    //select the digit by enabling the common cathode (sink)
    digitalWrite(digitPins[i], LOW);

    // write '0'
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 63);
    digitalWrite(latchPin, HIGH);
    delay(1000);
  }
}

This code will display a '0' one digit at a time, each for 1 second.  If this code works then I suspect the problem lies in the updateDisp() function.
NB: In your code, tempPin is setup twice as an input.

In the line shiftOut(dataPin, clockPin, MSBFIRST, 63);, the number 63 may actually be 252 depending on which way the wires A-G are wired to the shift register. You could always use 255 to turn on all bits from the shift register.


text:
Multiple arduino Wireless communication
I would like to know what device and model to use for an application where I will have 1 arduino as a master micro controller waiting to receive data from 5 slave arduino microcontrollers.
The Master arduino will be connected to local network via Ethernet cable so once it receive data from a Slave controller it needs to post to server the information, get a response back and in case the response is a "true" value then the Master need to talk back to the Slave in order to turn a LED on.
There will be cases when maybe 3 of the Slaves will send data at the same time, this doesn't mean at exactly the same millisecond. So I don't know if there will be data lost.
I was reading that Xbee maybe is the best device because it has a feature that will hold the data until there is a success communication with slave.

Is this a doable and "easy" task using Xbee? Anyone that already try to do something like this that can guide me?

I was reading that there is a device nRF24l01 that is very cheap and can do exactly what I need. Just that I don't really know how to start.

Appreciate any advice or help.

i would just use ESP8266s to combine the receiver hardware and the MCU into one cheap unit, capable of hundreds of peers and easily portable w/o interference concerns.

Also with the ESP8266 there is no "master" to send the data to first. Each one is its own master and just does the POST itself.

So what you recommend me is just to use ESP8266 directly posting to my network? I have to check that with my customer because they dont have WIFI in the area where we have the arduinos.

@dandavis ESP8266 allows you to have other ESP8266s as clients and have as the master?

yes, you can have one ESP act as a "wifi router" (AP) and the others as "clients" (STATION). The AP one can even perform a dual-role and iteself talk to a wifi router while accepting input from all the clients.

It really depends on the communication range and context required.
If your slaves are within 10-20 meters from the master device and the environment is not polluted (in terms of magnetic field) you can achieve good results with very inexpensive nRF24L01+ modules which operate in the 2.4GHz.
If you need to cover greater distances (in the order of 100 meters) or a polluted environment then you have to resort to shorter wavelengths or more powerful devices, but that brings in the question on how are you powering your slaves: on battery power those ranges get pretty power hungry.
Generally speaking I would say this question should be rejected as it's going to start a debate rather than provide a solution.
You can get some introductions on how to use nRF24L01+ modules simply searching online:

some posts on my blog
the Arduino library I always advice
a pretty valid guide

nRF24L01+ with power amp and SMA antenna I achieve 300m+ reliable communication in quite a polluted area (many WiFi access points around - housing estate with lots of internet users).

yup Majenko, in my tests I managed to achieve 900m, but I was in open space (no walls) even if pretty polluted (residential area with plenty of WiFi routers) using an SMA antenna, noise attenuation circuit and power amplification, but it was also drawing 400mA when transmitting (yes, just a short burst, but it's almost half an amp!). And anyway I wouldn't personally consider those reliable comm, but, as I said, it's a matter of context: IR could be better than radio depending on the context.... underwater you might want to go ultrasonic, as an example :-D

Really appreciate the feedback, i think thats the way I have to go, and also I will consider as the other people said using ESP8266 posting directly to server I guess.


text:
Write array to serial port
The Code Below now works:
void SendCTRL (String &input)
{
  const char *hin = input.c_str();    // Get character array
  int clen = input.length()/2;
  unsigned char cmd[clen+1]; // Leave a byte for null terminator
  for (int i=0; i < 2*clen; i+=2)
  {
    cmd[i/2] = dehex(hin[i])<<4 | dehex(hin[i+1]);
  }
  cmd[clen] = 0;                     // Null-byte terminator
  digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit
  for (int i=0; i< clen; i++)
  {
  RS485Serial.write(cmd[i]);   // Send string someplace
  //Serial.write(cmd[i]);
  }
  delay(clen/4);
  digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit
  Serial.println();

}

byte dehex(char c)
{
  // Get nibble value 0...15 from character c
  // Treat digit if c<'A', else letter
  return c<'A'? c & 0xF : 9 + (c & 0xF);
}

byte dehex(char c)
{
  // Get nibble value 0...15 from character c
  // Treat digit if c<'A', else letter
  return c<'A'? c & 0xF : 9 + (c & 0xF);
}

Input is a series of ASCII-encoded hex digits and getting the output to print the byte values of the hex.

There's some logic slightly askew with your length calculations:
int clen = input.length()/2;

Ok, so for a (say) 20 character string you have clen=10.
for (int i=0; i < clen; i+=2)

Ok, so for the first 10 characters of your 20 character string you take alternate ones (0, 2, 4, 6, 8)
What about the last 10 characters?  clen is 10, not 20, since you divided it by 2 at the start.
Decide if you want clen to be half the string length, then count double, or is the whole string length, and you divide it by 2 where you want the final string length. Or have two variables - one before and one after dividing by 2.
Oh, and you should pass your String parameter by reference so you don't duplicate the object and end up fragmenting your heap.
void SendCTRL (String &input)

I haven't gone into depth about the working of your dehex function, but this is the function I always use and works well:
unsigned char h2d(char hex)
{
    if(hex > 0x39) hex -= 7; // adjust for hex letters upper or lower case
    return(hex & 0xf);
}

Also you should or your values together, not add them:
cmd[i/2] = (dehex(hin[i])<<4) | dehex(hin[i+1]);

This would go some way to fixing your current issue, since | has a different precedence to +. At the moment you have effectively:
cmd[i/2] = dehex(hin[i]) << (4 + dehex(hin[i+1]));

since the + happens before the <<, whereas what you want is:
cmd[i/2] = (dehex(hin[i]) << 4) + dehex(hin[i+1]);

However with | instead you get
cmd[i/2] = (dehex(hin[i]) << 4) | dehex(hin[i+1]);

because the << happens before the |
Here is your code written in pure C to run on a PC (faster to debug and test than an Arduino when you're on Linux):
#include <stdio.h>
#include <string.h>

unsigned char dehex(char c)
{
  // Get nibble value 0...15 from character c
  // Treat digit if c<'A', else letter
  return c<'A'? c & 0xF : 9 + (c & 0xF);
}

void SendCTRL (const char *hin)
{
  int ilen = strlen(hin);
  int clen = ilen / 2;
  unsigned char cmd[clen+1]; // Leave a byte for null terminator
  for (int i=0; i < ilen; i+=2)
  {
    cmd[i/2] = dehex(hin[i])<<4 | dehex(hin[i+1]);
    printf("%02x\n", cmd[i/2]);
  }
  cmd[clen] = 0;                     // Null-byte terminator
  for (int i = 0; i < clen; i++) {
    printf("%c", cmd[i]);
  }
}

void main() {
    SendCTRL("010307E40001C549");
}

Ok! that got the writing working. Unfortunately, it just seems to output jibberish.

I have posted my version of a hex to dec converter. It may work better, or may not...

@Majenko,  c<'A'? c & 0xF : 9 + (c & 0xF) will work with a...f as well as A...F as representatives of 0xA...0xF.  Also, Addition vs Or makes no difference here, because the low 4 bits of  dehex(hin[i])<<4 are clear, and so are the high 4 bits of dehex(hin[i+1]).

@JamesWaldby-jwpat7 yes, it should all work fine in this situation - but it's good practice to get into the habit of combining with OR rather than with ADD.

Ok so my issue now is that my input string 010307E40001C549 should return me (as ASCII \code) \01\03\07\E4\00\01\C5I or (as U8) [1,3,7,228,0,1,197,73] Instead I'm getting (as ASCII) \100~@\EE any thoughts?

(as ASCII) \100~@\EE equates to (as U8) [16,48,126,64,238]

Because you're using + instead of | you have a precedence error. See my edit.

Switched to | for 010307E40001C549 I'm still getting
(as ASCII) \100~@\EE equates to (as U8) [16,48,126,64,238]
Updated Code above

Maybe the Arduino compiler is doing it slightly different then. Add brackets around the first part of the combination formula.

Oh, and you are still confused with your counting. You now have i++ instead of i+=2 which is wrong. Check my example (pure c) code for how to do it.


text:
Arduino Nano + (2* tlc5940) + 34 LEDs = Power Questions
This is an adapted layout for two tlc5940 hooked up to an Arduino nano. The original project can be found here. I am a little unsure about the capacitors and resistors as that project had it hooked up to a 5v wall plug.
My Design will be running a pattern of PWM, blinking and chasing lights. The two red lights are off of the TLC5940s circuits because reds need a different resistance. If i am wrong, please let me know as that would simplify things.

Also as is the way of the stack community, any other red flags you can point out would be greatly appreciated as i am new to this game.

TLC5940 is a constant current driver.

Also, its supply is given as 5.5V max.

No resisor in the red leds? As for the capacitor; it might not be needed, but doesn't hurt. I'd move the smaller capacitor as close to the TLC as possible.

Hey @Gerben I have added the resistors to the reds, i always forget them! Should i use two smaller capacitors so i can get them even closer to each tlc5940?

That would be ideal. Adding some decoupling capacitors near the chip can prevent (electrical) noise, and thus prevent weird behavior of the chip.

As Ignacio has mentioned the TLC5940 is a constant current driver. The 2kΩ resistor sets the current for the LEDs regardless of the forward voltage (or colour) or the supply voltage.
Also as Gerben says, move the 0.1µF (100nF) capacitor close to the TLC5940 as you can. There should be one for each TLC5940 since they are decoupling capacitors.
You might like to increase the capacitance of the electrolytic too. The purpose of that capacitor is to provide a low impedance energy source to supply the circuit (batteries are actually quite high impedance by comparison). Since you have lots of LEDs being controlled by PWM the current draw will be fluctuating wildly all the time, and lots of energy over brief periods will be wanted.
Another thing to watch, mentioned again by Ignacio, is the supply voltage for the TLC5940 is 5.5V absolute maximum. I wouldn't go much above 5V. Depending on what your batteries actually are you may be better running from 3 of them (4.5V alkaline AA - Ni-MH would be ~3.6V, so 4 of them, giving 4.8V, would be better in that situation).
I would also question your use of the TLC5940. They are not the easiest chips to drive requiring quite a strange protocol. Personally I prefer the TLC59116 which is the I2C variant of the same chip. Much easier to control from an Arduino, and requiring just 2 pins. Not so easy for bread-boarding though as they're SMD only.

Hi @majenko Thank you for the great explanation!  What size electrolytic capacitor would you suggest i use?

Whatever you have handy. 10µF minimum.


text:
Writing to flash Attiny 85
I set a project-goal for me: to make a very small compiler in Attiny.This compiler should read the code from user and translate it into code;then save it in some portion of the flash and jump there. I know this sounds impossible on Attiny85 but I want test self-programming. I read from various websites that the '85 does not have a "bootloader protection" like Atmga or Uno does. If it's true what are the functions used to write to the flash? (The only function I can thing of that access the flash is pgm_read_byte() but that is only for read).

There's an entire section in the datasheet devoted to this. Have you looked at it yet?

Maybe you can learn by reading and understanding an ATTiny85 bootloader, such as Micronucleus.

The datasheet contains a lot of information but I could not find code for writing to Flash (it is a long datasheet and I have no ideea what to look at so maybe I missed it). @Majenko ..yes that was my next step.Thank you.

The datasheet is written from a low-level perspective. If you were working with assembly it would be useful, but when programming in C you would be better with the AVR106 App Note

You could have a look at AmForth and how it writes to flash. http://amforth.sourceforge.net/

I understand assembly(I worked in nasm).Although there are some new instructions in thendatasheet(aleo in the bootloader).I'll have to study those


text:
how to drive 500W of leds
I am currently developing a project that needs 9 led stripes, each led stripe has 5 meters, 300 leds, it consumes 60W per stripe in a total of 540W...
This are the led stripes - 5M 12W/M 24V SMD 2835
This led stripes use a 24V power supply.
The thing is I want to drive them with an arduino and PWM. What would I need to do it. I was looking for something like CAT4101 but I never dealt with so much power before and I would like your advice.
Thanks

The led strips will have their own current limiting / drivers. A couple of quick calculations:

24V at 12W is (I=P/V) 12/24 = 0.5A per meter
5 meters = 0.5*5 = 2.5A

So each strip takes 2.5A. The CAT4101 is a 1A max driver, but since it is a constant current driver it's not suitable for a strip that has its own current control built in.
I suspect each meter consists of 10 chains of 6 LEDs with a current limiting resistor or two. Out of interest, calculations:

6 LEDs at (say) 3V forward voltage would be 18V.
24 - 18 = 6 volts to drop
500mA divided by 10 chains = 50mA
R=V/I = 6 / 0.05 = 120Ω current limiting resistors.
P=I²R = 0.05²×6 = 300mW dissipated from the resistors.

Instead all you need is an N-channel MOSFET as a low-side switch that can operate with that much current and not dissipate too much heat while switching. The more you derate the MOSFET the less heatsinking it would need.
A quick look on Digikey gave a possible match of PSMN022-30PL - 30V, 30A, 27mΩ (typ) at 4.5V gate voltage.

simulate this circuit – Schematic created using CircuitLab

And I would need one of those for each led stripe? What if I get a 600W power supply? I don't think that the leds have drivers at all? I was thinking on direct power supply connection.... I guess that would be mistake right?

Ideally, yes - spread the load nicely. However one, with proper heat sinking, should be able to do all of them together (22.5A) at a pinch.

sorry I edited the question: What if I get a 600W power supply? I don't think that the leds have drivers at all? I was thinking on direct power supply connection.... I guess that would be mistake right?

Do you have a link to the LED strips?

it's in portuguese, but google translate should handle it:

https://goo.gl/qXX2IQ

Yes, it has current limiting resistors. You can see them between every three LEDs. They have most likely split the resistance across a couple of resistors to spread the dissipation, so they can use smaller resistors. So direct supply connection and a MOSFET to switch them is fine.

And yes, as I thought - you can tell by the cut points (where the metal pads are) that they are parallel chains of 6 LEDs.

Let us continue this discussion in chat.


text:
float not a float
I am trying to read a SDM220 meter on my solar setup. I've been reading it using Modbus SCADA, so know it all works ok.
But I want to read it with my Arduino Mega 256. My problem is that when I run the code below the final value MtrKWh , is not float value. it's actual value is printed.
Here is a copy of the output.
17241 MtrKWh1 1129906176 MtrKWh1<<16 57737 MtrKWh2 1129963913 MtrKWh3 11299639.00 MtrKWh 2
the value '1129963913'       MtrKWh3,
if I turn it into Binary is
01000011010110011110000110001001,
if I convert this to binary using https://www.h-schmidt.net/FloatConverter/
it gives me the value
217.881,
the very value I expect. Am I missing some brackets somewhere?
So how do I get MtrKWh to print its float value?
I have left a lot of commented out bits to show the several things I have tried. Sorry if it appears messy, I will tidy it up once I solve this problem.
I'm sure it is something simple, but, I haven't been able to see it so far.
Any sugestions would be appreciated.
    // MtrV, MtrC, MtrW, MtrKWh
    //void AddressRegistry_0()
    result = sdm220_modbus.readInputRegisters(0x48, 2);
    //while (!result == 0) {
    // delay(10);
    // result = sdm220_modbus.readInputRegisters(0x156,4);
    //}
   if (result == sdm220_modbus.ku8MBSuccess)
   {
    // 1 Serial.println((node.getResponseBuffer(0x0D) + node.getResponseBuffer(0x0E) << 16)/100.0f);
    // 2 pvpower = ((long)node.getResponseBuffer(0x03) << 16 | node.getResponseBuffer(0x02)) / 100.0f;
    // 3 long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4;
    // 1 working ?? MtrKWh1 = (((long)sdm220_modbus.getResponseBuffer(0x0) + sdm220_modbus.getResponseBuffer(0x1) << 16)/6.f);
    // 2 working ?? MtrKWh1 = ((long)sdm220_modbus.getResponseBuffer(0x0) << 16 | sdm220_modbus.getResponseBuffer(0x1)) / 100.3f;
    // 3 working MtrKWh1 = (( sdm220_modbus.getResponseBuffer(0x0)  << 16) |  sdm220_modbus.getResponseBuffer(0x1))  / 16.3f;
    //
   // float MtrKWh0 =((float)(sdm220_modbus.getResponseBuffer( 0) << 16 | sdm220_modbus.getResponseBuffer( 1)));
    //      Serial.print(MtrKWh0);
    //    Serial.print(" MtrKWh0     ");

signed long MtrKWh1 = sdm220_modbus.getResponseBuffer(0x0);
Serial.print(" ");
Serial.print(MtrKWh1);
Serial.print(" MtrKWh1");

MtrKWh1 = MtrKWh1 << 16;
Serial.print(" ");
Serial.print(MtrKWh1);
Serial.print(" MtrKWh1<<16");

word MtrKWh2 = sdm220_modbus.getResponseBuffer(0x1);
Serial.print(" ");
Serial.print(MtrKWh2);
Serial.print(" MtrKWh2");

signed long MtrKWh3 = MtrKWh1 | MtrKWh2;
Serial.print(" ");
Serial.print(MtrKWh3);
Serial.print(" MtrKWh3");

float (MtrKWh) = float (MtrKWh3) / 10000.0;
Serial.print(" ");
Serial.print(MtrKWh);
Serial.print(" MtrKWh     ");

//uint32_t x = 0x3f322e3f;
//float y = *(float*)&x;
//Serial.print (y, 6);
// Serial.print(" MtrKWhxxx ");

   }
   else
   {
    rs485DataReceived = false;
    Serial.println("Fail sdm220_modbus.readInputRegisters(0x0, 1) ");
   }

You have your answer commented out in the source code. Conversion of type using pointers, not casting.

Or you could use reinterpret_cast if the compiler supports it - I've never tried.

Casting will convert an integer into a float with the same numeric value (1000 => 1000.000). Instead what is wanted is the overlaying of a float's structure on the memory of the integer value, which is what the nasty type-punning in the commented section is doing. Personally I'd use a union to overlay a 4-byte array over a float.

@majenko reinterpret_cast does exactly that. I think it's a C++11 thing though, and I don't know whether the Arduino compiler supports it.

I put this
reinterpret_cast(MtrKWh)
in the code, i get error during complie
invalid cast from type 'long int' to type 'float'
I thought that was he point of reinterpret_cast, to change type?
Have I got the syntax right?
signed long (MtrKWh) = float (MtrKWh3) / 10000.0;
Serial.print(" ");
Serial.print(MtrKWh);
reinterpret_cast<float>(MtrKWh);
Serial.print("   MtrKWh     ");

You need to convert the format by overlaying one type on top of the other, rather than casting from one type to another.
1000 as an integer cast to a floating point value is still 1000.
You have an example of how it can be done in comments:
//float y = *(float*)&x;

However this method is called type punning and is frowned upon (there are compiler options that can prevent it being used).  Instead using a union is a better option:
union ifloat {
    uint8_t bytes[4];
    float val;
};

void setup() {
    ifloat f;
    Serial.begin(115200);
    f.bytes[3] = 0x43;
    f.bytes[2] = 0x59;
    f.bytes[1] = 0xE1;
    f.bytes[0] = 0x89;
    Serial.println(f.val, 4);

}

void loop() {
}

So you can get the byte order right your current numeric value of 1129963913 is 0x4359E189 in hexadecimal. Byte 3 is therefore the most significant byte and byte 0 the least significant. Note that it can change from system to system depending on the endianness of the chip.
How it works is quite simple. You have 4 bytes in memory, and the union just gives you different views of those 4 bytes.
You can either see them as four individual bytes (f.bytes[0-3]) or as a floating point value (f.val).
You can understand more about how the four bytes describe the floating point number by understanding more about the IEEE 754 Single Precision Floating Point Format.

You can achieve the same thing using reinterpret_cast, but that has to be done using pointers, not the values, which makes it a little more complex to understand:
// Your incoming 32-bit value
uint32_t l = 1129963913;

// A pointer to the same memory with a different type
float *f = reinterpret_cast<float *>(&l);

// Print the *content* of the pointer interpreted as a float.
Serial.println(*f, 3);

Thanks for response. I think I saw a similar solution on my searches earlier. I found it difficult to understand/impliment. I have 2 words, MtrWhr1 and MtrWh2, do I need to convert these two words to bytes, then to hex, then use the code above to get the float conversion?

OK. So I never got the reinterpret_cast, thing to work. Went with Majenko's solution.
This code goes above Setup
// UNION, used to re-jig float
union ifloat {
uint8_t bytes[4];
float val;
};
// END UNION

And this is the modified code, with all the comments and bug print statements removed.
  // MtrV, MtrC, MtrW, MtrKWh
 //void AddressRegistry_0()
 result = sdm220_modbus.readInputRegisters(0x48, 2);
 if (result == sdm220_modbus.ku8MBSuccess)
 {
signed long MtrKWh1 = sdm220_modbus.getResponseBuffer(0x0);
word MtrKWh2 = sdm220_modbus.getResponseBuffer(0x1);
byte msb3 = MtrKWh1;
byte msb4 = MtrKWh1 >> 8;
byte msb1 = MtrKWh2;
byte msb2 = MtrKWh2 >> 8;
ifloat f;
f.bytes[3] = msb4;
f.bytes[2] = msb3;
f.bytes[1] = msb2;
f.bytes[0] = msb1;
Serial.println(f.val,3 );
  }
 else
 {
rs485DataReceived = false;
Serial.println("Fail sdm220_modbus.readInputRegisters(0x0, 1) ");
 }

And it is giving me the right numbers!
Thanks for input to all who did, it helps some times to be show which door to walk through.
Majenko, if you have time, and inclination, it would really help my understanding if you could describe your code. I am using it, but not sure how it works,or what most of it is doing. If you have the time.

Description added to my answer.


text:
What is the best way/module to talk to an Arduino from far away (WIFI)?
I am new to Arduino and IoT. I plan to build a product that I will connect to an app and they have to be able to communicate from a very far distance (kilometers).
Bluetooth is not a good option then (because the distance is too far). So would Wifi work? I read something about a module called esp8266 that might be what I am searching for.

esp8266 can communicate 100's of metres (I've seen claims of over 1km - but that would be with ideal conditions and directional antennas) ESP8266's big brother, the ESP32, has been apparently made to communicate over 10km - again, very ideal conditions and specific equipment required

Plus add on in esp32 you get Bluetooth but yet it's not having any arduino support for that.

Alright! A esp32 could be a good solution. I might need it for a bit longer distances though. But thanks a ton for your suggestion

I'd suggest looking into LORA.

Esp8266 range is about 400m. So if you have your mobile within 400m then you may be able to communicate. But for long distance communication I would not prefer but if you have any Internet connection available nearby esp then you may be able to transmit your messages via it. Well for long distance communication  I would prefer you to use any GSM shield in which you need to plug in a sim card and it can be used upto when you have coverage in that area.

Alright! Is is possible for iOS apps to communicate with GSM shields?

Arduino GSM Shield works the same as a mobile does. It uses the SIM Card to communicate. So as that suggests you can use it send Texts, Call anyone, and use the Data connection to connect to internet. Please refer the Arduino Page

Ah alright! I have a sm5100b-d at home that might be what I am searching for

I don't really now much but I think it might work I am not sure but it might work!

I don't really now much but I think it might work I am not sure but it might work!

The simplest option is to use GSM for the communication. Range isn't an issue, since point A isn't communicating with point B, instead point A and point B are both communicating via third party communication subsystem C which has a much greater coverage than anything you could build yourself.
I use GSM modules for communication with agricultural monitoring and control systems at remote locations. It works well, and you're pretty much guaranteed to have a signal.
For those times when GSM isn't a possibility (no signal, or the customer doesn't want the subscription cost) you really need line of sight between the two locations. Then you can use a highly directional antenna (e.g., parabolic dish or Yagi array) to extend any other suitable wireless communication signal over a long range (WiFi can reach tens of kilometres with parabolic dishes) and there are companies that specialise in that kind of equipment (such as this one that claims 8 mile range - of course you need two of them, one for each end of the link).  Of course, with some skill and determination it's possible to get incredibly long distances from WiFi. Not for your average user though...

appreciate your answer and help a ton!!

LoRa is apparently the most popular low-speed, low-power, wide-area network at the moment.
Many people use LoRa for direct point-to-point links around a kilometer.
Other people use LoRa for "last mile" wireless links as part of a LoRaWAN to some gateway hard-wired to the internet, much like a Wifi access point -- except trading off data rates in order to get longer wireless range than WiFi.
details:

"LoRa is de facto dominant" -- "LoRaWAN across the globe: LoRa Internet of Things networks overview"
LoRa range tests using the RFM95 Anarduino LoRa Modules, similar to the , LoRa IoT Development Kit (using a "LoRa Bee"), RFM95W LoRa Module for Arduino, RFM95W Breakout Board for LoRa, RFM95 LoRa mikroBUS Module, etc.
"LoRa range experiments Urban test" using the Microchip RN2483 module; I can't quite see which breakout board he's using -- I'm guessing it's one of the Sodaq LoRabee RN2483, the RN2483 LoRa Technology PICtail, the Azzy RN2483 breakout board, the Azzy LoRaWAN RN2483/RN2903 Breakout board , etc.
The Vinduino measures wind and soil moisture using an Arduino and reports back those measurements with a Globalsat LM-210 LoRa module
"LoRaWAN ... Range: 2-5km (urban environment), 15km (suburban environment)" --
"11 Internet of Things (IoT) Protocols You Need to Know About"
LoRaWAN Part 1: How to Get 15 km Wireless and 10-Year Battery Life for IoT
"low power wide area (LPWA) technologies have become popular. In various LPWA technologies, narrowband (NB)-IoT and long range (LoRa) are two leading technologies." -- "A survey on LPWA technology: LoRa and NB-IoT"
"The LoRa shield: an Open Source Arduino’s long-range communication module" apparently uses the Open-Electronics LoRa shield for Arduino - Mounted
"Building your own private LoRa network" mentions several different LoRa shields
The LoRa Alliance
arduino-lmic: the IBM LMIC (LoraMAC-in-C) library, slightly modified to run in the Arduino environment
"LoRa and Long Range Wireless IoT"
"The low data-rate (down to few bytes per second) and LoRa modulation lead to ... more than 22km (13.6 miles) in LOS links and up to 2km (1.2miles) in NLOS links in urban environment (going through buildings)." -- "Extreme Range Links: LoRa 868 / 900MHz SX1272 LoRa module for Arduino Waspmote and Raspberry Pi" tested a SX1272 LoRa module on a Multiprotocol Radio Shield on an Arduino Uno and links to a few other LoRa modules / LoRaWAN kits.


text:
ESP32 in Arduino-IDE with FS.h and SPIFFS
I'm working on a webserver on ESP32 in Arduino IDE and would like to load an html-file. Tried to use SPIFFS.open from the library FS.h from github.
Errormessage says SPIFFS was not declared in this scope. (As far as I can see, there's no bracket in the wrong place.)
I did not find any example for ESP32 and FS.h and desperately hope for some help. Thanks in advance.
Here is my code:

    #include "FS.h"
    #include "WiFi.h"
/Wifi Access data/
const char* ssid_ap = "AccessPoint";
const char* password_ap = "12345678";
const char * ssid_sta     = "";
const char * password_sta = "";
/* set global variables */
byte WiFiMode = 0;  // WIFI_STA = 1 = Workstation  WIFI_AP = 2  = Accesspoint
int request_counter;
String sHTML;
String sHTMLRequest;
/* Create instance of server on Port 80 */
WiFiServer server(80);
WiFiClient client;
/*
 * ******SETUP*******************************************************
 */
void setup() {
/initialize GPIO/
/*start serial communication */
  Serial.begin(115200);
  SPIFFS.format();
  Serial.println("Spiffs formatted");
/* start WiFi as workstation (STA), if not possible
   start as Acess Point
   initialize server */
  WiFi_Start_STA();
  if (WiFiMode == 0) WiFi_Start_AP();
}
/*
 * **LOOP*************************************************************
 */
void loop() {
/* Check if a client has connected */
  client = server.available();
  if (!client)
  {
    return;
  }
/*Wait for the client to send data */
  Serial.println("neuer Client verbunden");
  /*Count Aufruf der Seite: */
  request_counter ++;
  unsigned long clTimeout = millis()+250;
  while(!client.available() && (millis()clTimeout)
  {
    Serial.println("time-out bei Client-Verbindung!");
    return;
  }
/****** open html files  *******/
 SPIFFS.begin();
 File f = SPIFFS.open("/home.txt", "r");
    if (!f) {
    Serial.println("file open failed");
    }
    f.close();
}
/**********************************************************************
 *
 **************** FUNCTIONS ********************************************
 *

*/
/*
 * Fct tries to start WiFi in workstation mode,
 * if not possible sets WiFiMode=AP
 * starts server
 */
void WiFi_Start_STA() {
  unsigned long timeout;
WiFi.mode(WIFI_STA);   //  Try to start WiFi as Workstation
WiFi.begin(ssid_sta, password_sta);
  timeout = millis() + 12000L;
  while (WiFi.status() != WL_CONNECTED && millis() < timeout) {
  delay(10);
  }
if (WiFi.status() == WL_CONNECTED) {
    server.begin();
    WiFiMode = WIFI_STA;
Serial.print("Verbunden mit IP - Addresse: ");
    for (int i = 0; i < 3; i++) {
      Serial.print( WiFi.localIP()[i]);
      Serial.print(".");
    }
    Serial.println(WiFi.localIP()[3]);
}
  else {
    WiFi.mode(WIFI_OFF);
Serial.println("WLAN-Verbindungsaufbau fehlgeschlagen");
}

}
/*
 *starts WiFi in AP-mode
 *starts server
 */
void WiFi_Start_AP() {
  WiFi.mode(WIFI_AP);   // Access Point mode
  WiFi.softAP(ssid_ap, password_ap);
  server.begin();       // start server
  IPAddress ApIP = WiFi.softAPIP();   //read IP of Access Point
  WiFiMode = WIFI_AP;
Serial.print("ESP-Netzwerk: ");
  Serial.print(ssid_ap);
  Serial.print(" aufgebaut. ");
  Serial.print( " IP-Addresse: ");
  Serial.println(ApIP);
}
    <code>

https://github.com/copercini/arduino-esp32-SPIFFS
This library should help you.

I have this same problem after a new install and,
Looks like the link is dead.
Can anyone please take the time to explain how to fix this problem.

The answer is belated but since the question is still open...
The code does not include spiffs library. The line below should fix the problem.Note it should be below the the include statement for FS
include <SPIFFS.h>

So the code should look like
#include "FS.h"
#include "WiFi.h"
#include "SPIFFS.h"

at the time of the question esp32 arduino core didn't have SPIFFS library

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Programmatically Change Arduino Com Port Name
I have some devices that, when I plug in, will display a unique name, usually a serial number, as opposed to "COM #" is there any way I can have my Arduino Uno (or Mega) give itself a different name in my program's set up structure?
Edit: My purpose here is that I'm writing a program on the computer side that needs to find the Arduino among multiple possible COM ports. I'm deploying this program over multiple computers that I don't have admin access to so changing the registry is likely a non-starter.
Right now, I'm going through each port and sending a *idn?\n (which my program responds to with a specific string). For another device I have, I can search the possible connections for a port named [device serial number] and test that one first.

When I plug in my Arduino, I'd like it to identify to the computer as an arbitrary string specified in the setup phase of the code as opposed to "COM #" as it does by default

So you don't want the default name of that specific serial port that is COM# Am I correct ? Please correct me if I have mistaken.

What platform are you using to connect to your Arduino, Windows or Linux? (Suspect Windows)

"will display a unique name" .... where do they display this "unique name"?

I am using windows, That is a correct understanding. In terms of display location: when given the option on my computer to connect to various devices, I can select COM port 1 -> COM port N or a string that represents the serial number of a device like "Tektronix 25145134514"

If you read this So it says:
You'll have to change the software on the Arduino USB chip itself,
and you may need to modify the drivers for the Arduino USB interface
on the computer side. It's not trivial, and probably not worth it.

Then according to this you need to toggle and tinker with the Driver software

Wait that means it is not the correct answer. So according to your plan you need to maybe toggle with IDE that is instead of manually changing the ports you want the software to identify on its own. So for that purpose you have to tweak with Arduino board bootloader, and say it send a message to the Arduino IDE on startup . After that you have to tweak with Arduino ide source codes and then tweak it to Search for that message and then it reads down the address that is its COM

Thanks! That's too bad that there isn't an easier solution. (As a side note I think you mean to say "tinker with," in US English at least "tinkle," is slang for urinate XD )

tinkle and tinker are different things, just don't tinker with you winkle when tinkling :)

On Windows you can change the "Friendly names" assigned to devices and COM ports are devices.  The process is basically open the device manager, open the device properties, find the 'Device Key' and then locate that in the registry and change the 'Friendly Name' value.
See this page for more details:
https://www.eightforums.com/customization/15321-tutorial-how-change-device-names-device-manager.html

Ok, is there a way to do this on my Arduino so that it would be constant from computer to computer?

No.  The name is generated by the device driver on the PC.  The Arduino has nothing to do with it.

Often those names can be used to ensure that every time you plug into a specific USB port on the PC you get the same COM number.


text:
RasPi GPIO into Arduino Digital Inputs
So I'm making a Robot for my AP Comp Sci Class, and I'm borrowing an Arduino, as well as a Pi from the school. What I plan to do is have my Pi output from the normal GPIO pins and into the Arduino's digital inputs to "Tell" the Arduino what servos to run. The reason I'm doing it this way is so I don't have to screw with interfacing and all that crap. Is it safe for the Arduino? If so, what would I need for resistors and such?

Didn't you already ask this?

I was told to move it here instead of having it on Stackexchange

You will need to expand on "I don't have to screw with interfacing and all that crap", because you are trying to do exactly that.

I think he means communication protocols (which would be the sensible way to do things)...

I think you are talking about writing to a GPIO and that being received by the Arduino if so the Pi is 3.3v and the Arduino is 5V so you will need a "Level Shifter" to boost the voltage to 5V so the Arduino can read the signals.
Other than that there is no problem with doing what you are doing, apart from its a lazy solution and you won't score very highly.  I know you don't want to mess with protocols but if you can use I2C from the Pi then use that to send messages to the Arduino.  Your protocol could be as simple as 1 byte saying which pin you want to light up, you'll get better marks.
Edit
To use I2C is really quite simple because someone has done almost all the work for you in Wire.h, so just include that file and then to send a byteits simply a case of:
Wire.beginTransmission(device_address);
Wire.write(data_byte);
Wire.endTransmission();

Reading data sheets for devices makes it look a lot harder with all the transmission sequence diagrams, but you don't need to worry about that its all done for you.  The hardest bit to remember is the pull up resistors on the data lines.
Have a look at these links for more information:

http://tronixstuff.com/2010/10/20/tutorial-arduino-and-the-i2c-bus/
http://howtomechatronics.com/tutorials/arduino/how-i2c-communication-works-and-how-to-use-it-with-arduino/
https://www.arduino.cc/en/Tutorial/MasterReader

That was exactly what I was talking about,  my one problem is that I have no clue about how to use I2C correctly (i find it Kinda confusing)

There is a little bit more to it than that but not much.


text:
Any good way to inverse a function?
I'm guessing that the answer to this is "no," but I'm curious if there is any way to save writing some code by specifying a function to do the opposite of whatever another function does. For example the inverse of:
int FW (int in)
{
  int out=2+in;
  Return out
}

would be
int RV (int in)
{
  int out=in-2;
  Return out
}

However, would there be any way to call the inverse of FW() if it was a more complicated function that still had one and only one input for each output?

Ask this question on stackoverflow and use c tag .You will get much better answers there

You could crate a more general function like; MOVE(int in, int direction){}

@Sniper, this is hardly a C question.  More of a theory question.  Per Halting Problem on wikipedia,  “Alan Turing proved in 1936 that a general algorithm to solve the halting problem for all possible program-input pairs cannot exist”, providing an easy answer of No to the question in its general form, and with more effort probably to the  “one and only one input for each output” subquestion as well. ¶ ATE-ENGE, of course there are lots of ways to get function inverses for particular functions, but from Turing's result not in general

lol! Well if Turing said I can't do it, I suppose I shouldn't try XD

Now if it could be used to figure out the original two factors multiplied together to produce a big number, then you would be on to something.

No. A function does what it does and that is all. No other function can know what some other function does.
You could write a function that does different things depending on what parameters you pass to it, but that's the closest you can get, and is pretty pointless when you can just write different functions anyway.

That's what I had thought. Thanks for confirming.

You can trivially see this to be true: imagine a function which returns 1 if the integer argument is odd, 0 if it is even. It's impossible to reverse this in reality, regardless of what you know about the code and what the code knows about the code.


text:
What is the meaning of [type]* for arrays?
I've seen * used with arrays in some programs but not in others. The page on arrays doesn't mention it at all, but I often see it near functions when values are being passed.
Where would I find more information on this?

There are several possible usages, each with its own meaning, so you are going to have to ask about a specific example.  One possibility is the fact that you can have an array of pointers, a pointer to an array, etc, but there is also the related fact that that arrays readily and gracefully degrade to pointers.

Ok! Looks like I was talking about pointers Time to learn today

You are asking about Pointers -
 https://www.tutorialspoint.com/cprogramming/c_pointers.htm.


text:
Create an a message from two inputs[Programming Help]
I'm a bit new to this and I have the following function that I'm having trouble getting it to compile. The intent is to create a message to write out to a software serial port. Inputs are two int values of Function address and the data passed to the device while the output is a series of char characters
void Create_Message(int Address, int Data)
{
  byte S1Add = 1;
  byte FuCode = 2;
  byte AddHi = Address>>8;
  byte AddLo = Address;
  byte DatHi = Data>>8;
  byte DatLo = Data;
  byte AdDa[] = {AddHi,AddLo,DatHi,DatLo};
  unsigned int crc=CRC(AdDa,4);
  byte CrcHi = crc >> 8;
  byte CRCLo = crc & 0xFF;
 /*U8 Slave Address, U8, Function Code, U16 Address, U16 Data, U16 CRC
 * to
 *[U8 Address Split High, U8 Address Split Low, U8 Data Split High, U8 Data Split Low, U8 Function Code]
 */
 unsigned char cmd[]={S1Add,FuCode,AddHi,AddLo,DatHi,DatLo,CrcHi,CRCLo};

  digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit
  for (int i=0; i< clen; i++)
  {
    RS485Serial.write(cmd[i]);   // Send string someplace
    Serial.write(cmd[i]); //echo back
  }
  digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit
}

byte CRC(byte AdDa, int Size )
{
unsigned int crc16 = 0xFFFF;
int pos = 0;
int i = 0;

/*Write CRC*/
  for (pos = 0; pos < Size; pos++) {
    crc16 ^= AdDa[pos];          // XOR byte into least sig. byte of crc

    for (i = 8; i != 0; i--) {    // Loop over each bit
      if ((crc16 & 0x0001) != 0) {      // If the LSB is set
        crc16 >>= 1;                    // Shift right and XOR 0xA001
        crc16 ^= 0xA001;
      }
      else                            // Else LSB is not set
        crc16 >>= 1;                    // Just shift right
    }
  }
  /*Note, this number has low and high bytes swapped,
  so use it accordingly (or swap bytes)*/
  byte crc[]={crc16>>8,crc16};
  return crc;
}

Any help with optomizition would also be greatly appreciated :)

What errors and warnings does the compiler give? Which lines are we looking at?

I downvoted this question because it does not incorporate suggestions from  comments and answer at byte Array to CRC calculation,  your previous question.

I'm voting to close this question as off-topic because it is not an Arduino specific question, it is asking for basic optimisation pointers that would be better answered elsewhere.

This question is better suited for the code review SE site.

If you want help with optimisation then "Code Review" would be the better forum.
Its very difficult to optimise code that's hard to read.  You have used an inconsistent formatting style (which might be because of the post but your failure to fix it indicates a lack of interest in the answers.
You passed all you function arguments by value, you should pass them by constant reference.
You are doing a number of implicit casts, because you have mismatched types.
You are sending a byte to serial.write, what happens if the value is outside of the printable range, it would be better to print this as a hex number.
I assume someone has already pointed out CRC should return a byte*.
As for the algorithm, the code isn't readable enough to comment on that.

Ok, I'll check there, Also I guess I missed something from my previous question as well. In terms of formatting, where can I find style guidelines that would improve my code readability?


text:
Arduino-based mains frequency monitor
I'm looking to put together a simple mains frequency monitor based on the Arduino platform. The mains here are 250 V @ 50 Hz, but obviously these fluctuate slightly, which is the whole point of the exercise. (I am not interested in capturing voltage fluctuations, only frequency fluctuations).
I have never used any Arduino products before, but I am familiar with PIC-based MCUs. I understand Arduino should be somewhat simpler. Also, I am not an electronics engineer.
Presumably, the Arduino will sample the mains frequency for a second or two, and then report the result somehow. I guess the easiest way is for a computer connected to the Arduino by USB to receive the result and act accordingly. Otherwise, other options include adding an Ethernet module to the Arduino and having it HTTP POST the result to a web server.
(I assume doing this naive method is preferable to recording a time series and then performing a Fourier transform?)
Size isn't a huge concern, but a compact device is preferable over a larger one as I'll be 3D-printing a custom enclosure for it. Therefore I would like to use the Arduino Nano if it's suitable.
Here is what I have so far:

The 250V mains will be half-rectified with an IN4004 (?) transistor (together with a 1K resistor and 0.22 uF cap), and that will go into a 4N35 optocoupler.
A digital (?) GPIO pin from the Arduino goes into the base of the 4N35 and emitter goes to GND.
The Arduino samples for a short time the number of pulses on that pin, does a simple calculation, and reports the result.

Here are my uncertainties so far:

Based on my research, I believe the Arduino can reliably be powered by USB. If this is correct, this would be ideal as it would avoid me having to build a low voltage DC power supply for it.
How stable is the clock on the Arduino? How many decimal places on the frequency can I realistically achieve?
I presume I'll need to debounce the result from the optocoupler? Will there be some noise as the transistor transitions between states? Are there built-in debouncing functions or will I need to write my own? How is this likely to affect available clock cycles and therefore the accuracy of the measurement?
I've seen PIC projects where it interacts with the computer by emulating a keyboard. While simple, this wouldn't be ideal as the computer it's connected to must also remain usable. The software processing the result should run in the background while a user can continue using the computer. How simple is it to write some software (in C#) that will recognise the Arduino connected via USB, and communicate with that device in particular?

I also welcome any other comments and suggestions. Thank you.
Edit: Following these helpful comments and suggestions, I've made some revisions and asked a follow-up question.

The stability of the mains will exceed the accuracy of the Arduino clock by several orders of magnitude. Arduino usually uses a ceramic resonator and you would be lucky if this is accurate to 1%.  If you wanted to monitor the short term mains frequency deviations you first need to use a stable reference (atomic clock or GPS).

@Milliways: [citation needed] ;-) The inaccuracy of the Arduino clock is not an issue if you calibrate it away. And the mains may not be as stable as you seem to believe. Here is a mains stability measurement showing an Allan deviation higher than 1e-4 for 40 s ≤ τ ≤ 1 h. In the same τ range, an Arduino with a ceramic resonator has been measured to be better than 1e-6, whereas a quartz-based one is better than 1e-8, more than four orders of magnitude better than mains.

@EdgarBonet I do not deny there are short term variations in mains frequency. Most networks (at least in advanced countries) adjust mains frequency so the total number of cycles is constant over longer periods (typically 24 hours). My experience as a telecommunications engineer has confirmed this (at least in Australia). Ceramic resonators can be stable (if not accurate) PROVIDED the temperature is kept constant. Your second reference (one measurement) claiming MOST use a crystal is just plain wrong. I am sure there are more Unos than all others combined.

@Milliways: The second reference is old: nowadays most Arduinos use ceramic resonators, as I stated in my answer. But that does not invalidate the measurements which, by the way, were not done with a controlled temperature.

Either way, I want the highest resolution and best tolerance possible. Given mains in Australia is required to be 50Hz +/- 0.5Hz, I probably want 4 decimal places if possible. I'm trying to find a way to determine which Arduino boards use crystals for the MCU clock and which use ceramic resonators. From what I can see, they all have a crystal, but presumably that's for the USB interface? How can I get a list of Arduinos that use crystals? Otherwise I'll just scrap the Arduino idea and do it all myself with a PIC.

Too many questions to answer in a comment. See my amended answer.

I understand Arduino should be somewhat simpler [than PIC].

The whole Arduino platform (boards, core library and IDE) makes it super
easy to get started and do simple things. However, if you want to
“push the limits” and use the full potential of the MCU, you may have to
dig into low-level programming, and this has a steep learning curve.

The 250V mains will be half-rectified with an IN4004 (?) transistor
(together with a 1K resistor and 0.22uF cap), and that will go into a
4N35 optocoupler.

1 kΩ seems way too low to me: your resistor will dissipate on
average 31 W, and it will burn unless it is a heavy-duty power
resistor. You should choose a resistor that limits the current to a
value low enough to avoid overheating, but still high enough to reliably
turn on the optocoupler. If these two constraints end up being
incompatible, you will need a step-down transformer in addition to (not
instead of) the optocoupler.

A digital (?) GPIO pin from the Arudino goes into the base of the 4N35
and emitter goes to GND.

The base of the optocoupler is typically left floating. You connect the
Arduino input to the collector, using either the internal or an external
pullup resistor, and you ground the emitter.

I believe the Arduino can reliably be powered by USB.

Yes, powering through USB is fine. The Arduino itself draws very little
power. Only when it is powering something else you may worry about
power limits. Here it would seem your Arduino will only be sourcing a
very small amount of current into the output transistor of your
optocoupler, so you will be fine.

How stable is the clock on the Arduino?

Terrible. Most Arduinos are clocked off a ceramic resonator. These
are typically specified with 0.5% frequency tolerance, but their
frequency is constantly fluctuating, and is also strongly dependent on
ambient temperature. This makes those Arduinos grossly unsuited for any
job requiring precise timings. I would recommend you get an Arduino
sporting a real quartz crystal, like the Leonardo or the Micro. A quartz
crystal can be quite inaccurate, but at least its frequency is stable.
It's orders of magnitude more stable than a ceramic resonator. C.f.
for example this article about the Arduino clock frequency
accuracy.

I presume I'll need to debounce the result from the optocoupler?

If the capacitor after your half-wave rectifier is well dimensioned,
your signal should be clean and not need debouncing. The Arduino digital
inputs all have Schmitt triggers which clean up the input noise as
long as it is not excessive. If you really need debouncing (check with a
scope if you can), well... there are no provisions for doing so in the
Arduino core library, but there is a Debounce tutorial among the
examples shipped with the Arduino IDE, and there are a few third party
debounce libraries floating around the Web.

How simple is it to write some software (in C#) that will recognise
the Arduino connected via USB, and communicate with that device in
particular?

As stated in other answers, your Arduino will be seen by your computer
as a virtual serial port. I don't know C#, but any decent programming
language should allow you to easily read data from a serial port.
Measuring method:
You will time one or several periods of the input signal. There are
several ways of doing so. In roughly increasing order of complexity and
accuracy:

You continuously monitor the digital input, in a loop, and whenever
you see a transition from LOW to HIGH you record the current time
using micros().

You use an interrupt pin as the input and you have the interrupt
handler record the time with micros().

You use the input capture facility of your 16-bit timer running at
the full CPU speed.

The methods using micros() have a resolution of 4 µs. Both will
give you some software-induced jitter because they depend on the timing
of your program execution. The advice given by GuitarPicker: “Keep your
code predictable, using as few conditional branches as possible that
might alter how long your code takes to run each cycle” is relevant only
to the first method. The interrupt method is immune to your main loop
timing, but it is still affected by the CPU processing other interrupts.
The input capture method will give you single-cycle resolution and
accuracy, with zero software-induced jitter. That would be my first
choice, but it requires digging into the MCU datasheet and doing some
low-level programming.

Addendum: Here are some tentative answers to a comment posted by
Ozzah to his own question:

I probably want 4 decimal places if possible.

If you want 10−4 absolute accuracy, you may need to
calibrate your clock, even if it is a crystal. If you only require
10−4 stability (variations of the frequency), then even a
ceramic resonator may be (barely) up to the task, if you don't mind
recalibrating it every few weeks, and assuming your indoor temperature
doesn't vary by more than ≈ 10°C.

I want the highest resolution and best tolerance possible.

Then a quartz crystal is definitely a plus. It's roughly 100 times
more stable than the ceramic resonator.
But if you really want the “best”, you may as well follow Milliways'
advice and get a GPS reference. Some options, in increasing order of
price and accuracy:

A simple GPS module for the Arduino. Make sure you get one with a
1PPS output (a “one pulse per second” reference signal). You may want
an external antenna for better reception.
A GPSDO (GPS disciplined oscillator). This is typically a lab-grade
frequency standard consisting of an OCXO (oven-controlled crystal
oscillator) disciplined by a feedback loop into tracking GPS time. It
gives the same long-term stability as the simple GPS module but has
far better short-term stability.
A rubidium-based GPSDO. This is similar to the above but has also a
rubidium atomic frequency reference. Still better short-term
stability. Now we are talking about stabilities in the
10−11 to 10−12 range. Provably overkill for
your use case.

From the software point of view, I would recommend you start with the
interrupt method, just to get a prototype working easily, and then go to
the input capture method, as it will give you the best accuracy. It
should be possible to be cycle-accurate with the interrupt method, but
that would require some non-trivial tweaks.
Note also that the Arduinos based on the ATmega32U4 (Leonardo and Micro
at least) have two 16-bit timers with input capture capability. You
can then time both the mains signal and a 1PPS reference in parallel. If
your Arduino has only one 16-bit timer (like the Nano), you would have
to time one of the signals with the interrupt method.

I'm trying to find a way to determine which Arduino boards use
crystals for the MCU clock and which use ceramic resonators. From what
I can see, they all have a crystal, but presumably that's for the USB
interface?

Yes, the USB/serial interface is clocked off a crystal more often than
the main MCU. The Arduinos that do not have a separate USB/serial
bridge (like those based on the ATmega32U4) seem to have the main MCU
clocked off a crystal.

How can I get a list of Arduinos that use crystals?

It's often stated in the product page. E.g., the page of the Arduino
Micro states
(emphasis mine): “It has 20 digital input/output pins (of which 7 can be
used as PWM outputs and 12 as analog inputs), a 16 MHz crystal
oscillator, a micro USB connection, an ICSP header, and a reset
button.”
Arguably, the info is not very prominent, and a compiled list would be
useful. I think this could be a very good question to ask in this site.

Thanks so much for your insightful answer. I had later revised it to 6K resistor and then finally decided it would be best just to transform down to a lower voltage, probably 5V. I will look into the models with quartz crystals. Is it simple to replace the ceramic resonator with a quartz? Is it just a matter of swapping out some components?

@Ozzah: Replacing the ceramic resonator with a quartz doesn't look like an easy task. It's a tiny SMD component, you will need to find a quartz small enough to fit in there, and most quartz crystals require a pair of capacitors that you would also have to fit, together with the crystal, into the footprint of the resonator.

It sounds like you're well on your way to creating a solid project.  I will attempt to answer some questions and offer some suggestions on approaching this.
Rather than counting the number of AC pulses per time period, you might get better results seeing how many Arduino clock ticks you get between a sampling of say, 50 (debounced) pulses.  This will give you bigger numbers to work with.  Doing the opposite (seeing how many pulses per time period) will not give the same precision.  If you only got 49 pulses in a second, did you just barely miss the 50th, or was it a whole 2% off?  Since the Arduino clock can count much faster, it would be better to count those ticks instead.

Arduinos can be reliably powered by USB, as long as you don't draw too much current.  Your application sounds like it shouldn't draw much at all.
The clock on the Arduino isn't going to compare with using a separate real-time clock circuit, but it should be good enough to measure trends and differences.  Keep your code predictable, using as few conditional branches as possible that might alter how long your code takes to run each cycle.
Debouncing is probably a very good idea in this situation.  There are several debouncing libraries available for the Arduino, or you can roll your own.  Once again, the library should written as to not introduce inconsistent delays into the code.  For this reason, it might be better to write your own specifically suited for this application.  You might need to borrow an oscilloscope and see how long the pulses are from your optocoupler circuit.  The closer you can get them to being a 0V/5V square wave, the better.
Arduinos come in many flavors.  Some can emulate keyboards, but most act natively as serial ports.  If you can read data from a serial port, then you can read the output from the Arduino.  This should be trivial in C#, or just use a terminal emulator or the Arduino IDE's serial console to view the results.  Once again, if you are outputting data while still measuring, then you should use use fixed width output so that the program takes the same amount of time to run each cycle.  It would be far more accurate instead to take your measurements silently, and output the results afterward later so that you don't have to account for serial port buffer delays.  Take another "flush" delay before starting measurement cycle again.

I would use a step-down transformer with that 1N4004 rectifier diode to limit the peak rectified voltages to less than the Arduino's safe input voltage. I would also be inclined to add a zener diode to ground at the Arduino's input to "clamp" or limit that input voltage to whatever your Arduino's safe upper limit is.
At some point you might also find it beneficial to double the 50hz using a full-wave rectifier to give you more pulses to count for finer resolution.
A low current fuse in there somewhere wouldn't be a bad idea either.

So I'm not an electronic engineer, but I don't understand why I need to bring the voltage down to the Arduino's range? Isn't that the whole point of the optocoupler? The input end runs at 250V and the output end runs at whatever voltage the Arduino is running at?

It's a safety issue at the very least. A catastrophic failure of the opto & everything is gone. At least with a "wall bug" style transformer, you've given yourself & your device a large safety margin.
I assume your opto will be triggered at line voltage & frequency to subsequently switch a 3.3 or 5v bus to an Arduino input pin at the 50hz line rate.
The opto you've chosen turns ON at ~1 volt & it needs a current limit of ~10ma thru it. You'll need to calculate a dropping resistor value to bring the rectified peak voltage down so that the opto isn't overloaded in either category. You'll need to also compensate for the eventual surge/peak voltages well above the typical line voltages.
There could conceivably be enough constant "noise" riding in on the line that prevents the opto from regularly seeing the "zero crossing" moment that your pulse counter relies on.
Transforming that line voltage to a much lower level decreases ambient line noise by the same transformer ratio, increases safety & makes it easier for the opto to detect the zero crossing in the presence of line noise etc.
bc

Thanks. I think I'll drop down to ~5V with a transformer as you suggest.

It wouldn't hurt to do both the transformer and the opto.  I've seen wall transformers fail with higher voltages than their usual output.  I'm thinking back to a cheap powered USB hub I encountered that kept zapping flash drives (back when they were new and expensive).

Based on my research, I believe the Arduino can reliably be powered by USB.

it can also be powered by the mains directly. ST wrote such an application note for its STM8 but the basic principle is the same. The beauty of this approach is that your zero cross detection can be done without the use of an optocoupler, directly through a gpio pin.

How stable is the clock on the Arduino? How many decimal places on the frequency can I realistically achieve?

depending on your board. crystals are usually specified to 20ppm but typically within 10ppm at room temperature. resonators, which some arduino uses, are 0.1 - 1%.
if you are n't too picky, even the internal oscillators will do -> you can average the measurement over a long period of time to minimize jitter.

I presume I'll need to debounce the result from the optocoupler?

generally no.
when you measure frequencies, you typically count the input signal. for low frequencies like the mains, you do the other way around: count the internal clock and use the input signal to gate its counting.
This allows frequency calculation down to quite a few decimal points: you should average approximately 8M counts per half cycle.
that's a lot of effective digits.


text:
How to run my IDUINO Yun Shields stand-alone?
Experts,
How can I power and communicate with the IDUINO shield stand-alone? In other words, without any additional uC for it to plug into.
Failing in that, can a Nano (cheaper, smaller) be wired to give the Yun what it needs?

Can you paste a link to IDUINO? Or do you mean Arduino?

http://www.geeetech.com/wiki/index.php/Iduino_Yun_Shield

Yes, you can. All you need do is provide it with a regulated 5V supply on the 5V pin and it should power up and boot.
There's not a lot of IO on it though, so connecting to sensors and such would be hard, which is where the Arduino comes in handy. You communicate using the UART, so any microcontroller with a UART can be connected to it.


text:
NRF24L01 integrated antenna exposed out of the box
I'm going to try my hand at making a few sensors that are to report status to a central server. To make them wireless, I'm going with nRF24L01 modules. I intend to enclose the sensors (Arduino Mini Pro + nRF24L01 + battery pack + a couple of other small components) in a simple PVC box.
A couple of the sensors would be about 10 meters away from the server, which, as far as specifications go, is about the maximum range of the radio modules. Especially the ones with the integrated antenna that I'm using. I thought that maybe I could squeeze some radio performance by exposing the antenna, so that the radio signal isn't attenuated by the PVC case. I could carve a small opening in the lid and have the nRF24L01 stick out, so that the electronics would be protected inside but the antenna strip would enjoy open air.
I would like some thoughts on this idea. I'm especially trying to understand if I just had the most novel idea ever, since I can't seem to find anything about it on the net. Has anyone ever tried this in real life? Does it make sense? Is it worth the trouble?  I'm not looking for a theoretical analysis (I get that fine), only for actual experience. Thank you.

How much suffers the range of your nRF24L01 while in the box compared to outside of the box? Maybe you can try another box that does not shield off your wireless signal?

You would do better adding a dipole to the board and ensuring they are orientated correctly. http://www.instructables.com/id/Enhanced-NRF24L01/

Only metal or other conductive materials (like water) impact the magnetic field. Also consider both PCB and Dipole antennas are not omni-directional: correct orientation might also be beneficial, even if it is probably a brittle solution.

@Kwasmich I still haven't tested the prototype. I'm still in the design phase, but I wanted to make sure I considered a possible case improvement (if it actually were an improvement, which does not seem to be the case).

Where did you get that 10meter figure from? Sound a bit low to me. Maybe indoors with multiple walls, but otherwise the range is much further. You could test different channels to see which works best in your situation. Also lowering the speed will increase the range.

@Gerben Yes, I'm referring to indoors, a few rooms away, with WiFi, and good old European brick walls from sixty years ago. I'll surely try different channels as you suggest; I'm not sure how to act on the transmission speed, though.

If I remember correctly the NRF24 has 3 speeds. 2MBit, 1MBit, and 250KBit per second.

In general no, this would make little or no difference. PVC has very little effect on RF signals.
After all, the antenna on your typical WiFi router is inside a PVC tube and it doesn't suffer from it.
Instead you would do better constructing a dipole antenna from a couple of pieces of carefully measured wire.
For instance this instructable tells you how.

Thank you! I will test the performance and consider building the dipole.


text:
Voltage divider arduino 5v and Ethernet board 3.3
I have an Arduino Nano 5v module and I just received an Ethernet Interface Board - ENC28J60 that runs at 3.3v. (https://www.sparkfun.com/products/765)
Might sound a dumb question but I will power the Ethernet board from a Voltage regulator that can deliver 3.3v but then I have to connect via SPI to my Arduino controller. I guess I can't connect my Arduino pins directly to the Ethernet board right? because HIGH in the pin will be 5v instead of 3.3v.

Do I need to add a Voltage divider for those pins connections? And in case I need to what resistance values are the right ones to use?

Thanks

Yep, you need Bi-directional logic voltage converter https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide

@martynas those are more geared towards I2C, since I2C has a bidirectional data line.

Wooow nice!!! yes I have seen those Bi directional logic voltage converters now I know whats that for. Appreciat it

And I guess that logic voltage converters are only used for the Pins right... for powering the module then is right to use a voltage regulator such as the LM3940 IC.

Yup you are correct.

From experience with 3.3v ESP8266es with 5v Arduinos, only the signals to the 3.3v device need to be converted (5v high -> 3.3v high). A 3.3v level to the Arduino is high enough for 5v logic to still read it as HIGH. That means you can get away with just a voltage divider on each of the Arduino -> ENC28J60 pins.


text:
Error in IR receiver project
I'm trying to receive remote information with an IR receiver and this is my code:
#include <IRremote.h>

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
  delay(100);
}

I tried to upload this to Arduino and it says:
exit status 1
redefinition of 'int RECV_PIN'

How can I fix this?

I can see no reason for it unless you didn't install the library properly, or the code you show isn't actually the code you are compiling.

I compiled your code. There is no compilation error. Probably, library problem. Install it properly.

Apparently the name RECV_PIN is used somewhere else, presumably in IRRemote.h -- although not in any version of it I can find.  Anyway, just change the name of RECV_PIN to something which doesn't conflict.
For example:
int MY_RECV_PIN = 11;
IRrecv irrecv(MY_RECV_PIN);