UDP socket, select one of multiple clients - sockets

here's what I'm trying to do:
I have 4 clocks and one PC on the network. I (PC) want to get the time from any of the clocks.
The idea:
Every clock uses UDP Broadcast (broadcast because I don't know the PC's IP). The PC gets a first dataset(time) and from then on only looks at datasets from this clock. (To not get confused by slight timedifferences between the clocks)
Clocks=Clients:
- socket
- bind to port 1234
- sendto(broadcast,'1234')
PC=Server
- socket
- bind to port 1234
- recvfrom(data,client_addr) //extract client_addr from first received data
- connect(client_addr) //to only receive data from this client
- recvfrom()
1: Is this the correct way to do this? Or is there a better option?
2: What can I do, if I want more than one application on the PC to get the time-data? Can I just copy the code and use it? My impression was, that port 1234 is now blocked from the first application that gets the bind.
(I guess SO_REUSEADDR won't work because only ONE application then gets the data AND I don't know which one it is going to be)
Regards

1: Is this the correct way to do this?
Yes.
Or is there a better option?
Can't think of one off-hand.
2: What can I do, if I want more than one application on the PC to get the time-data?
Use SO_REUSEADDR.
Can I just copy the code and use it?
Yes.
My impression was, that port 1234 is now blocked from the first application that gets the bind.
No.
(I guess SO_REUSEADDR won't work because only ONE application then gets the data AND I don't know which one it is going to be)
Wrong guess. Why guess about it at all? Why not try it? Much more reliable than guessing, and quicker than asking questions here too.

Related

How to read Analog Output Holding Registers on Advantech ADAM 6717 through ModBus TCP

I've been exploring the ADAM 6717 from Advantech.
This is the ModBus address table for said device:
At first I wanted to modify the value of the Digital output channel 0(DO0), so, as can be seen from the picture above, such address is the 0x0017.
I succeed at this by using a ModBus tool and the following settings:
Sending either "On" or "Off", turns On and off a LED connected to that output. Everything runs smoothly according to my expectation up to this point.
The problem arises when I want to read the Analog Input channel 6 or equivalently, address 400431~40044.
Since that address lies on the Analog Output Holding Registers part of the address table, I though that the following settings would accomplish the job:
However, as can be seen above, the reading shows 0.0 when there is actually 6V connected to that input (a potentiometer)
It is worth mentioning that I've made sure to enable the AI6 channel as well as setting it to Voltage mode instead of current. Also, the web utility for the device shows the AI6 reading correctly as I change the potentiometer's resistance value.
So the problem doesn't lie in the connection from the potentiometer to the AI6 but somewhere else.
Out of nothing and leaving aside what I think I know on this topic, I though of changing the function from 0x03 to 0x04
However, the response is exactly the same.
It bugs me that I can read and write values to the output coils but not the Analog output holding registers.
Is there any configuration that I might be missing over here?
Thanks in advance.
Device settings:
IP address: 10.0.0.1
Port in which the ModBus service is running: 5020

Trouble with communication with usb B type machine with Matlab

I am using matlab to communicate with several machines.
I am trying to connect with LCC25 (Liquid crystal retarder controller made by Thorlabs) using usb b to usb a cable.
I made a code like this.
clear all; clc;
%%
ss=serial('COM7','BaudRate',9600,'DataBits',8);
set(ss,'Parity','none');
set(ss,'Terminator','LF');
fopen(ss);
fprintf(ss,'*idn?');
aa=fscanf(ss)
fclose(ss)
Then I get "Warning : Unsuccessful read : A timeout occurred before the Terminator was reached aa=="
Is there any problem in my code?
I am also interested in buying the LCC25 and controlling it with MATLAB, so this is very interesting for me and I would love to find out whether it works...
To debug your code, I am wondering what happens when you comment out everything but:
ss=serial('COM7','BaudRate',9600,'DataBits',8);
set(ss,'Parity','none');
set(ss,'Terminator','LF');
fopen(ss);
Since then we can now if the problem is in establishing the connection itself (which you should not run every time btw!), or in trying to send a command to the device...
If the object creation is succesful, you should see something like this:
Serial Port Object : Serial-COM4
Communication Settings
Port: COM7
BaudRate: 9600
Terminator: 'LF'
Communication State
Status: closed
RecordStatus: off
Read/Write State
TransferStatus: idle
BytesAvailable: 0
ValuesReceived: 0
ValuesSent: 0
Then you can try to add run
fopen(ss)
fscanf(ss)
in a seperate file, and see what the output is. If all of this works, you can start to try sending commands using the 'fprintf' command, but make sure not to run the 'serial' and 'fopen' command every
I am wondering where you obtained the command string '*idn?', did you find this in the help file? The same for the terminator 'LF', are you sure this is the correct terminator to use for the LCC25? When reading the error message you received, I suspect the problem to be that you might need to use other terminators, such as 'CR'.

I2C read - repeated start needed?

I have a doubt regarding read operation in I2C, bit banging. The protocol which I am following for read as below:
Start-slave address with write-ack-register loc-ack-stop. ...... Start-slave address with read-ack-read data-stop.
I am reading data as FFh which is wrong.
My doubt is, before sending the another start, do in need to send stop or can continue the another start for reading data without stop, which actually is a repeated start. Does sending a stop bit or not makes any difference. Also can someone tell what can be the possible reason if data read is FFh. But I can guarantee that write operation is successful, after seeing the scope shot. Please guide me.
Thanks
The i2c protocol works like this
WRITE:
send START
write slave address with last bit as WRITE ACCESS(0)
write sub-address: this is usually the address of the register you what to write to; if not applicable skip to 4.
write data
send STOP
Each byte you write to the slave device should be answered with an ACK if the operation was successful.
READ:
send START
write slave address with last bit as WRITE ACCESS(0)
write sub-address: this is usually the address of the register you what to read from
send START (this is a second start condition - a restart)
write slave address with last bit as READ ACCESS(1)
read data
send STOP
All write and read operations (except the last read) are answered with a ACK if successful.
So in the case of a restart you don't send a second Stop.
As far as the 0xFF read result is concerned, you need to check the datasheet of the device, but some will return this value if the data you are trying to read is not available, yet!
Hope this helps.
I just had this issue and found the reason: if you receive FFh in reading all the time, you are missing the repeated start.

Checking private network for local devices with a certain port open (iPhone/Objective C)

I've spent the whole day creating a system between my Mac and iPhone where i have used cocoaasyncsocket to create a listen server on my mac and a client on my iPhone. The basic idea is to leave the app on the mac running while the computer is on and then when I wish to transfer data from the iPhone app, fire up the app an it connects and sends the data... I have this system working exactly how I want it to function however I have 1 issue what I have been trying to solve for about 4 hours in total!
I wanted to create something what scans my wireless network for my mac with the listener running... I thought this would be simple, but I was wrong. I have searched high and low with no luck on the case and I am using stackoverflow as my last resort.
My current plan was to "autoscan" by retrieving the internal IP of the iPhone (ie 192.168.1.94) then use that to figure out what the other IP's on the network will be (192.168.1.0-254), now I know what IP's to scan i can loop through each one and check to see if the port is open/I get a response.
Now I want to do this as quick as possible however I haven't been able to get ANYTHING to give me accurate results...
Using connectToAddress:error: in the cocoaasyncsocket will simply just return true for every one of the 255 different IP addresses, so will any other reachability functions that I have come across... I have read that it is because they only check to see if the connection gets made and don't care about what happens at the other end so I need to think of something else.
My only other solution that I can think of, is to maybe ping each internal IP and see if i get a response but im not sure if this is going to take up too much time having to go through 255 IP addresses... and then, once i get what IP's are active I still then have to check to see if the port is open somehow :/
If anyone here knows how it can be done or has any better idea how I can check for the open port (i'm not very good with networking) I would be VERY grateful.
Thanks for reading,
Liam
Ok, I had a pay around today and I managed to get it working using Bonjour!
As it took me time to figure it all out I thought I will help anyone else out...
First off, on the listener side we need to set up a NSNetService, this can be done like so:
listenService = [[NSNetService alloc] initWithDomain:#"" type:#"_appname._tcp" name:#"Display Name" port:2427];
[listenService setDelegate:self]; //make sure you include the NSNetServiceDelegate
[listenService publish];
You can then plug into the NSNetServiceDelegate to make sure the service was published successfully and I used Bonjour Browser to check that my service was running fine (and it was)...
Then on the client we need to search for the service using [NSNetServiceBrowser][3]... This can be done like so:
serviceBrowser = [[NSNetServiceBrowser alloc] init];
[serviceBrowser setDelegate:self]; //remember to include NSNetServiceBrowserDelegate
[serviceBrowser searchForServicesOfType:#"_appname._tcp" inDomain:#""];
If you then include the NSNetServiceBrowserDelegate methods you can listen in to
netServiceBrowser:didFindService:moreComing:
You must then retain the service, give it a delegate and then resolve the service... Then if you listen into the NSNetServiceDeligate for the netServiceDidResolveAddress: you can then run the following code to convert the sockaddr into a readable IP address:
#include <arpa/inet.h>
-(void)netServiceDidResolveAddress:(NSNetService *)sender {
for (NSData* data in [sender addresses]) {
char addressBuffer[100];
struct sockaddr_in* socketAddress = (struct sockaddr_in*) [data bytes];
int sockFamily = socketAddress->sin_family;
if (sockFamily == AF_INET ) {//|| sockFamily == AF_INET6) { /*only support ipv4 atm*/
const char* addressStr = inet_ntop(sockFamily,
&(socketAddress->sin_addr), addressBuffer,
sizeof(addressBuffer));
int port = ntohs(socketAddress->sin_port);
if (addressStr && port) {
//you now have the services IP and Port.. all done
}
}
}
[sender release];}
Hope this helps anyone who is stuck with this.. Note that I borrowed parts of other samples/ instructions into one complete post what explains the whole system.
Enjoy.
I haven't worked with it myself but basically Bonjour is actually what you are looking for it's purpose is publishing and discovery of services

Improve Arduino WiFly latency using protol

I have an Arduino with a WiFly shield, everything works perfectly!
The thing is, when I want to turn on an LED, I open in my
webbrowser:
192.168.1.120/ledon/
(I made a program which handles this URL).
But the thing is; when I make a request, I must wait 1-2 seconds before I can do another one.
So, it is very long, and if I want to control motors, it is just too long.
So, instead of using an HTTP request, I want to use something else which can be faster.
Something "super fast".
I just need to tell the Arduino:
- go direction 1
- go direction 2...
- turn on LED
- turn off LED
- tell me the light level (which return a int)
So it is just about a small amount of data.
Can you show me a way? (Telnet, UDP, OSC?)
For your arduino, have a look at just using sockets or even encoding the data in the URL requested.
You shouldnt get less than about 0.8 Seconds Lag maximum.
How big is your program for handling the Url /ledon/ ?
Using pure packets (usually TCP) from your computer to the arduino is faster sometimes..
But you may need to code a application to handle the packets on the pc.
There is the option of Javascript to parse data back and forth e.g. reading the light level and such.