Go Down

Topic: How to use UNO and Wifi to replicate an analog voltage? (Read 955 times) previous topic - next topic

jc12cl

Hi All, I have just gone through the UNO starter kit so am only a beginner.

My project in simple terms:  I need to replicate an analog voltage at another location on my property and thought I could use my wifi network and a pair of UNOs with wifi modules to do this.


In more detail:

I have a commercial irrigation controller mounted in a shed at one end of my property which controls solenoids in the back yard.  At the other end (approx. 60m away) in the front yard I have more solenoids which are not connected to anything yet.  I want to use the existing controller to activate the front yard solenoids as well (as it is convenient to program all the times and durations at the one location).  There are spare stations on the controller (24v DC output) which I can use but there is no way to run physical wiring from the back to the front yard.  The shed has a wifi extender which is on the same network as the house on the front of the property where the front yard solenoids are located.  The network connection between the shed and the house is achieved via ethernet over mains wiring (powerline ethernet).


My plan/concept is as follows:

Hardwire 24v output from irrigation controller to a relay to pass a lower voltage (eg: 5v) or digital signal to the UNO.  Use the UNO+wifi module to transmit the ON state of this signal to the network extender in the shed so that it is then available on the network in the house. Use a second UNO+wifi module within wifi reach of the house which sees the state of the signal and then outputs a digital signal to a relay that passes a 24v DC voltage to the wiring that connects to the solenoid in the front yard.

See the attached schematic of the concept.


I need help with the following:


1. Is the concept OK/sensible?  Or is there an obvious other or better way to achieve the same result via Arduino HW and code?

2. What is the best hardware solution at both ends?  Is there a single module with wifi inbuilt or do I need to connect a wifi module to something like a UNO (I already have 1x UNO)?  Basically, what HW should I use?

3. The code to achieve the sending and receiving of the signal (ON state).  I'm not expecting someone to have a sketch already created for this exact situation but if there is an example of a similar project or general guidance on what is required it would help greatly.

If anyone is able to help with the above it would be most appreciated.

Thanks.


 

Hiddenvision

#1
Jul 08, 2019, 10:30 pm Last Edit: Jul 08, 2019, 11:03 pm by Hiddenvision
Have you thought of using the ESP8266 module.

It has the WiFi built in and up to approx. 10 I/O.

The Arduino Environment is still used to write code and program the device.
Ohh, it also has up to 1MB code space and supports OTA reprogramming.
And you can use the spare Flash as a mini file system of 2MB.

For this sort of IOT/WiFi application it may give the fastest and lowest powered solution.
Each ESP can work as both a Client and server so they just have to be in range of each other to find their way back to the network.

You could either mesh a bunch of individual ESP units or Switch up to 10 solenoids per unit, or more if you expanded with other electronics.

Running each solenoid with a single ESP has advantages where you can run all of them from the same pair of power wires.

You may even be able to make them solar powered depending on the obvious conditions and restrictions.

Also if the two ESP locations are within range then they can simply connect directly to each other and not need any connection to your home wifi at all, cutting out the extender and other parts.

There are many examples to do most things on the ESP8266.
Well worth a look.

If you do not already have one then purchase something with the full pin count, 4MB flash and the usb, psu and reset bits onboard. Some boards even have external antenna connection. Something like the nodeMCU ESP12 or similar.


Having said that in answer to the other questions, it all looks fine.
the code would be pretty easy I suspect whatever route you decided.


Just remember to consider Wifi/network security when doing anything like this.
You do not want to leave yourself exposed to possible naf issues.

jc12cl

Thanks Hiddenvision.  As suggested I've gone with 2x NodeMCU 12s.

I've gone through many online examples to familiarise myself with the code to do basic stuff with the ESP8266 so I can connect to an existing home wifi network and can turn things connected to the MCU on/off via a webpage..etc..


What I now need to do is to get both MCUs to communicate to each other over the existing home wifi network.  I don't want them to connect directly to each other, I need them to go via the existing network.  There seems to be many good examples online showing how to code the IDE to make them connect directly but only few that that show how to do this through an existing network.

I tried the example from:  https://www.instructables.com/id/WiFi-Communication-Between-Two-ESP8266-Based-MCU-T/

It has .ino files to download and a series of instructions below:

Things you have to do to launch the server:
-Connect one MCU to a PC with USB cable.
-Open the "wifi_server_01.ino".
-Replace the asterisks "****" with the SSID and the password of your home WiFi router.
-Open the settings of your home WiFi router and choose a free IP address which is out of the DHCP range.
-Set the IP of your server (row15).
-Gateway will be the IP of your WiFi router.
-Upload the program.
-Run the serial monitor of the Arduino IDE.

Things you have to do to launch the client(s):
-Run an additional Arduino IDE.
-Open the "wifi_client_01.ino".
-Replace the asterisks "****" with the SSID and the password of your home WiFi router.
-Put the IP address of your server into the 15th row.
-Upload the program.
-Run the serial monitor for the new Arduino IDE also.


I changed the SSID and Password to match my existing network in both .ino sketches and uploaded them to each of the MCUs and powered them up but nothing seem to be transmitted/received between them.


I'm not clear what needs to be done w.r.t the "free IP address and Gateway" as mentioned in the instructions so I think this is where the problem lies.  The sketches already have addresses for these but I don't know if these can stay as is or if they need to be changed...and if so how do I find what to change them to from my router?  I'm very green on networking topics.


If anyone could clarify what I should do here....or suggest a different example sketch I should use to get the desired result it would be most appreciated.'


Thanks.

Hiddenvision

Hey JC,
those examples look like they should work.
Would have been best as dhcp (autoIP).

But as long as the gateway is correct and the two IP's are not already used it should do something.
You should be able to check those with any old device.
Make sure that the IP's are in the same range as the gateway.
So if on your PC/Android/IOS device you have a gateway of 192.168.1.??? you need to use IP's like 192.168.1.xxx


Hang in there you are 90% of the way !

Let me find one or two of the examples I used.


Hiddenvision

#4
Jul 13, 2019, 01:42 am Last Edit: Jul 13, 2019, 01:53 am by Hiddenvision
Although far more complex a process, using websockets is another easy way for the two to communicate. The example is pretty clear and small.

https://github.com/Links2004/arduinoWebSockets

Websockets are great because they create a two way connection so either device can talk to the other. Not saying that websockets is the direction but with the esp it is quicker to simply try out an existing example than to think about it for too long.

Perhaps a far more complex method is EasyMesh!

I cannot find an exact example of "easy" on the ESP.
Well I can , they are all pretty easy..!...

The best thing is to just look at lots of examples even if the project seems unrelated.
Different people have different ways to get what they need from the device.

From various methods to connect to a network and also present themselves as an accesspoint.
 I'll continue to look at my previous projects to find something that may suit.

I guess you will make the irrigation controller end the server.
and the valve end with the relay the slave.

Get familur with the SPIFFS LIB.
If you have 4MB flash on the boards then use 2MB spiffs.
And make sure you set the speeds to HIGH on everything including the upload speed.

A good bit of fallback code is to open the ESP as an accesspoint if it cannot connect to a network.
That way you can connect to it with a tablet if needed and setup or view settings. Some examples have a very simple interface and some have far more complex options.


In the long term you will need to either manage your home network and its IP's or switch back to using DHCP (auto IP).
If you are going to assign static IP's on your home network you must at least be able to have a good guess at what range your dhcp server(router) hands out so you can avoid conflicts.
What options your router offers is unknown.

Good routers will normally try to give out the same IP to the same device in DHCP.
You can also Name the ESP device and then find it by name rather than address.
but it all depends on your environment/equipment.

pedropena

Although far more complex a process, using websockets is another easy way for the two to communicate. The example is pretty clear and small.

https://github.com/Links2004/arduinoWebSockets

Websockets are great because they create a two way connection so either device can talk to the other. Not saying that websockets is the direction but with the esp it is quicker to simply try out an existing example than to think about it for too long.

Perhaps a far more complex method is EasyMesh!

I cannot find an exact example of "google street view" on the ESP.
Well I can , they are all pretty easy..!...

The best thing is to just look at lots of examples even if the project seems unrelated.
Different people have different ways to get what they need from the device.

From various methods to connect to a network and also present themselves as an accesspoint.
 I'll continue to look at my previous projects to find something that may suit.

I guess you will make the irrigation controller end the server.
and the valve end with the relay the slave.

Get familur with the SPIFFS LIB.
If you have 4MB flash on the boards then use 2MB spiffs.
And make sure you set the speeds to HIGH on everything including the upload speed.

A good bit of fallback code is to open the ESP as an accesspoint if it cannot connect to a network.
That way you can connect to it with a tablet if needed and setup or view settings. Some examples have a very simple interface and some have far more complex options.


In the long term you will need to either manage your home network and its IP's or switch back to using DHCP (auto IP).
If you are going to assign static IP's on your home network you must at least be able to have a good guess at what range your dhcp server(router) hands out so you can avoid conflicts.
What options your router offers is unknown.

Good routers will normally try to give out the same IP to the same device in DHCP.
You can also Name the ESP device and then find it by name rather than address.
but it all depends on your environment/equipment.

Ok, that is clear now. Thank your for your answer.

jc12cl

Hi Hiddenvision,

Thanks for the advice.  I managed to get the IP issue resolved so didn't have to go down the websocket path.  I now have the server and client connected to the wifi network and communicating together passing info (Strings) between them.  I am able to use the data received to switch on/off some relays at the client end to control the irrigation solenoids, so job done.

I could leave everything as is because it functions as desired however I notice that the data being transmitted hangs momentarily from time to time.  Both the server and client stay alive but every 20 seconds or so both hang/pause for about 5 seconds.  I see this in both the serial monitor output and the actual behaviour of the client relay output (I use some LEDs to visualise the output).  The data freezes at the last value and stays like this until it stops hanging and then updates as normal until the next hang occurs.

I'm concerned the hang is a symptom of poor coding technique I've used (I'm pretty new at this) and that it might cause a crash/shutdown or unreliable behaviour.  It appears the cause of the hang originates on the client side but i'm not sure. I tried to clean up the code as much as I know how but can't see what the cause might be.

Attached are the sketches for both the server and client for reference.


is there anything obvious in either or both sketches that could create this hang?

Hiddenvision

#7
Jul 22, 2019, 06:03 am Last Edit: Jul 22, 2019, 06:27 am by Hiddenvision
Hi JC,
Nice clean code that fits on a page.

the only bit that may cause an issue is rapid multiple connections to the server device.
Part of the IP protocol holds a bit of junk behind after each connection for a while.
I forget if that was on the client side or the server, or both.

If you just slow it down a little does it help.
Add this to the top of the loop of the client code.
Code: [Select]

void loop(){
  if ((askTimer + 1000) > millis()){return;}
  askTimer = millis();




This is one of those things that would be better via something like websockets or similar if you need fast response to a change.
Only because you are not making and breaking the connection each time so it is much faster for pinging info back and forth without the time overhead and also the minor memory munch.
And it is also two way then, either the server or the client can send packets.

You can add a simple serial print of the remaining memory of the esp after each connection to the server to see if it is leaking. Guess you could also print the same on the Server side to see if that displays the same issues.

Code: [Select]

void get_ram_left(){
    RAM_HEAPSIZE = String(system_get_free_heap_size());
//    if (RAM_HEAPSIZE.toInt() > RAM_HEAPMAX.toInt()){RAM_HEAPMAX = RAM_HEAPSIZE;}
//    if (RAM_HEAPSIZE.toInt() < RAM_HEAPMIN.toInt()){RAM_HEAPMIN = RAM_HEAPSIZE;}
}


Just a thought but it maybe easier to manage both client and server code in the same project.
That way for this sort of dedicated connection everything is all together and easy to edit.

Code: [Select]

// Comment this out to compile the server code
#define asclient

#ifdef asclient
  do the client things
#else
 do the server things
#endif


But I guess that is just a personal preference.

There was a bit in setup() where you had
Code: [Select]

String StationStatus = "0-0-0-0";


Drop the String from the start of that line as it is already typed and global.
re-typing like that may make it local to the function.
But that would not have done anything to disturb things.

Not much else to say, if it is working Well done.
Have a play with websockets or other types of connections they may give a more robust solution.

A few nice things to look at is doing OTA updates via Wifi.
If you have a little webserver on your network or on the web you can host the firmware updates on that and then the devices just check from time to time or when you press a button.
You can do the same with OTA updates to the filesystem if you start to use that also.
Both of those will make using the ESP a joy as you then hardly have to actually connect to the device with wires and it is also much faster to update using OTA.

As I may have mentioned, just keep looking at different examples of how people setup and use various features of the ESP, even if the project is not directly related to what you need.

jc12cl

Hi Hiddenvision,

I slowed down the client with the askTimer as suggested and things look more stable now.
So when both client and server are on the same network (identical SSID) its doing everything as intended.  Thanks for all your help.
I've attached the final client and server sketches for anyone to copy/reference if they like (v002). They just need to enter their network SSID and password.


The last hurdle for me now is to have the server connected to the wifi router in the shed which is a poweline extender and the client connected to the main wifi router which is in the house.  Both routers have different SSIDs but I was hoping that becasue the extender was just "extending" the same network from the house and the IP address is the same that the client and server would conect and see each other as if they were on the same network/SSID.  I tried and unfortunately it didn't work.  The string from the server isn't recieved by the client even though they both are connected to their respective routers.

I'm sure there is a way around this but it seems like a specific networking topic rather than ESP8266 related so I'll move the question to the networking thread of the forum unless anyone here has any ideas.

Hiddenvision

Cool stuff.

Glad to see you got it up and running.

Different SSID won't matter as long as they are on the same network.

Humm, puzzeling,
Guessing that you connect to the extension network with a smartphone and it works OK.?

jc12cl

Yes, the powerline extender network works fine. I have another device (the irrigation controller) permanently connected via wifi to the extender and it is always online and whenever I go near the extender my phone autodetects and connects to it with no issues.  Its been running for nearly a year now and never skipped a beat.  I didn't think the SSIDs would matter either but something about it doesn't work.  I'm assuming its something in the IP, Gateway, Subnet values or the WiFi.server (80) in the server sketch (which i'm not really sure what it does).

For reference the home router and extender both share the same IP and Gateway below:

IPv4:        192.168.20.16/24
Gateway:  192.168.20.1

Not sure if the /24 is relevant or not.

Hiddenvision

Have not read the Sketch so unaware of how you've setup.

If you are on Manual IP you just need to make sure that the Gateway, Subnet and perhaps DNS IP's are the same as what you get given on your smartphone or PC's

The IP just needs to be in the same range as what you get allocated via DHCP but you must make sure you do not use an existing one or you will get IP conflicts.

The Subnet is a set of bit Mask values filtering out unwanted number ranges, or something like that.

I'll take a peek at the Sketches and see what your doing.

Hiddenvision

#12
Aug 04, 2019, 05:50 pm Last Edit: Aug 04, 2019, 05:53 pm by Hiddenvision
Ahh, Make sure you do not have the same IP address for both the client and server.
I see they were both set at xx.20.80.
Subnet is fine for the range
Gateway I guess works also.

As mentioned make sure that you do not use a STATIC IP that is likely to be auto allocated by DHCP.
See what IP you are give on your PC's or tablets and use something far away.

So if you are normally auto allocated xx.20.2 and upwards then pick something like xx.20.250 & 251 to avoid conflicts. There will be a way to find out and or edit the allocation range on your router but another topic.

There is also a way to Name the modules and then you should be able to refer to them by name rather than needing to know the IP

Hiddenvision

#13
Aug 04, 2019, 06:01 pm Last Edit: Aug 04, 2019, 06:13 pm by Hiddenvision
EDIT:
Ahh forget what I just said. I gotta learn to read.!

I see the server module has a static address of 192.168.20.80 and the client is using DHCP cool.

So re looking at the code I cannot see any reason why it should not work.
But I did not look hard, even the second time round.

But in the server code where you are serial.printing the current status you may want to only send out on change and then perhaps at 1 or 5 second intervals

Code: [Select]


bool printit=false;
if (laststatus != currentstatus){printit=true;}
if ((laststatustime + 5000) < millis()){printit=true;}
if(printit){
  Serial.print(thestuff);
  laststatustime = millis();
  laststatus = currentstatus;
}




Go Up