The Arduino default Ethernet library class contains an IPAddress variable type. What is this IPAddress for? Why should I use it and why is it not used for the gateway and subnet IPs in the official example?
It just, like you said, a type of variable (such as int (integer)) that can store a IP address. Using integers, you cannot add the .s needed in the IP address. Also, the library only accepts integers, because with strings, things "can get messy." For example, if you have 1 in a string, you cannot add that with another number. However, if you have the integer variable type with the value of 1, it would add easily.
How can I use this?:
On Arduino's EthernetIpAdress page, there is this code:
#include <Ethernet.h>
// network configuration. gateway and subnet are optional.
// the media access control (ethernet hardware) address for the shield:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// the router's gateway address:
byte gateway[] = { 10, 0, 0, 1 };
// the subnet:
byte subnet[] = { 255, 255, 0, 0 };
EthernetServer server = EthernetServer(23);
//the IP address is dependent on your network
IPAddress ip(192,168,1,1);
void setup()
{
// initialize the ethernet device
Ethernet.begin(mac, ip, gateway, subnet);
// start listening for clients
server.begin();
}
void loop()
{
//print out the IP address
Serial.println(myIPaddress);
}
On the line IPAddress ip(192,168,1,1);, it creates a variable that holds the IP address. In the line Ethernet.begin(mac, ip, gateway, subnet); the variable is looked up and given to the Ethernet library. I don't know what the advantage would be, besides trying to prevent people from using the integer type and making it look cleaner. It could look up the automatically issued IP address and then store it for later so if it goes into an "idle mode," it can ask for the same IP address so it is almost like a dynamic IP that wouldn't interfere with other devices and would reset when the reset button is pushed. I'm sure that there is some use for it, but I cannot think of one. I just wanted to tell you what it is and how to use it. I would think though that it would be easier just to use #define IPadress 192.168.1.1 or a similar thing if you wanted it to easily be changed or to be more user readable.
Related
I have a scd30 sensor wired to an arduino uno. The scd30 works on theh I2c protocol. I am able to read data live on the serial monitor on the arduino IDE. I have an ethernet shield on my arduino. I would like the arduino to communicate with a field agent which will upload the data to the internet.
I have tried numerous modbus tcp libraries and dont seem to be getting anywhere. I can connect my arduino to the field agent but whenever it sends data I get a 0x02 exception code - Illegal data address. This is the Library im using https://github.com/andresarmento/modbus-arduino/tree/master/libraries/ModbusIP/examples
I believe the right way to go about it is through holding registers but im not sure how to do this when using i2c. The connection is fine, the problem is the format. any help is appreciated thanks.
/*
Reading CO2, humidity and temperature from the SCD30
This example prints the current CO2 level, relative humidity, and temperature in C.
*/
#include <SPI.h>
#include <Ethernet.h>
#include <Modbus.h>
#include <ModbusIP.h>
#include <Wire.h>
#include <Streaming.h>
#include "SparkFun_SCD30_Arduino_Library.h"
SCD30 airSensor;
//Modbus Registers Offsets (0-9999)
const int SENSOR_ISTS = 100;
//ModbusIP object
ModbusIP mb;
long ts;
void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println("SCD30 Example");
// The media access control (ethernet hardware) address for the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// The IP address for the shield
byte ip[] = { 000 , 00,0, 00 };
byte gateway[] = { 0, 0, 0, 0 };
byte subnet[] = { 255, 255, 255, 0 };
//Config Modbus IP
mb.config(mac, ip,gateway,subnet);
// Add SWITCH_ISTS register - Use addIsts() for digital inputs
mb.addHreg(SENSOR_ISTS);
airSensor.begin(); //This will cause readings to occur every two seconds
}
void loop()
{
mb.task();
mb.Hreg(SENSOR_ISTS, digitalRead(airSensor.getTemperature()));
}
I have read your problem.
In my view you first have to create a local server, somewhere like thingspace (https://thingspace.verizon.com/) or other online local servers, from there you can easily handle the data coming from the sensors.
You are using a code from library so it must be correct in any way. So, from my view you should check the data transactions.
wish my ans helps you
thanks!
The ModbusIP library expects from you that you supply the value of the register. The AirSensor library gives you that value.
Set the register value to Hreg:
mb.Hreg(SENSOR_ISTS, airSensor.getTemperature());
I tested your sketch without the sensor library and it is working. Client was my java test client I use to test access to Modbus TCP registers of my photovoltaic system.
Make sure that the client calls "0x03 - Read Holding Registers" and test address 100 and 101 because some modbus clients offsets are 1-based.
I'm trying to communicate using UDP an Arduino UNO + Ethernet Board with a PC, but can't do it properly.
Facts:
Arduino code has 2 blocks: first block send a constant message each 5 seconds to the PC. Second block has been implemented as a ECHO (returns what receives)
UDP is correctly initializated
At begining, Arduino starts sending the message "Hello PC!" each 5 seconds, but the UDP.beginPacket doesn't return 1 (as it is supposed to do when it works properly).
in the PC side I have wireshark and PacketSender to check the tx/rx UDP communication.
Wireshart doesn't detect any incoming packages from Arduino when it has been resetted.
A UDP package "Hello arduino!" is sent from the PC to Arduino, throught PacketSender. This packed is received correctly in the Arduino and sent back to PC. Wireshark identify tx UDP packet from PC and the same rx UDP packet from Arduino. This works properly.
Buuuuuuuuuttttttt...... then, after sending a UDP message from the PC and receive the ECHO, the messages from Arduino each 5 seconds start reaching the PC.
First message received on PC after the ECHO, has 21 bytes (although the message sended is supposed to have 11 bytes). The message received is "C!hello hellhello PC!", so there is some kind of buffer trash with "hello PC!" at the end.
The weird thing is that after this, each 5 seconds the PC receives an UDP packet, each time 9 bytes longer (hello PC! is 9 bytes message), and as in the first message received from Arduino, at the end of the message you can find "hello PC!". Here is an example of the 9th message received "PC!hello PC!!lhello PC!45hello!llo!helhello PC!hellhello!ohello PC!hello Phello PC!" (95 bytes length).
I use the standard Arduino Ethernet libraries, so I don't know what is happening and why it doesn't send anything until first message arrives to Arduino (and no idea why it is increasing each time it is sent).
I tested Arduino with Raspberry with Raspbian to ensure the problem wasn't on the PC side, and the Raspberry received the same erratic UDP behaviour.
Arduino Code:
#include <SPI.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern#cs.stanford.edu 12/30/2008
byte mac\[\] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x3D};
IPAddress ip(192, 168, 1, 6); //IP of the arduino ethernet board
char link_IP\[\] = {192, 168, 1, 3}; //IP of the PC
unsigned int localPort = 51115; // local port to listen on
char message\[\] = "hello PC!"; //message intended to sended from the arduino
char packetBuffer\[UDP_TX_PACKET_MAX_SIZE\]; // UDP_TX_PACKET_MAX_SIZE = 24
unsigned long millis_before = millis(); //variable for delaying 5 seconds the message
EthernetUDP Udp;
void setup()
{
Serial.begin(9600); //serial com for debugging
Ethernet.begin(mac, ip); //starting Ethernet
if (Udp.begin(localPort)==1) Serial.println("port UDP is open"); //starting UDP on 51115
else while(1); //if UDP not open, infinte bucle
}
void loop()
{
if (millis_before + 5000 < millis()) //loop for waiting 5 seconds between messages
{
if (Udp.beginPacket(link_IP, 51115)==1) Serial.print("TX ready - "); // UDP packet to PC port 51115, if beginPacket returns 1 is OK
Serial.print("Lenght:");
Serial.print(Udp.write(message, 9)); //returns the length of the message
if (Udp.endPacket()==1) Serial.println(" - Sent!"); //if endPacket returns 1, is OK
millis_before = millis(); //reset timer
}
delay(10);
int packetSize = Udp.parsePacket(); //check size of UDP packet
if (packetSize)
{
IPAddress remote = Udp.remoteIP(); //save remote IP
for (int i = 0; i < 4; i++) //bucle for printing the remote IP
{
Serial.print(remote\[i\], DEC);
if (i < 3) Serial.print(".");
}
Serial.print(", port ");
Serial.println(Udp.remotePort()); //printing the remote port
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); // read the packet into packetBufffer
// send a echo to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(packetBuffer, packetSize);
Udp.endPacket();
}
}
Here you can find the PacketSender and Wireshark captures after sending the first message to Arduino and receive the ECHO:
wireshark capture
packet sender capture
I apreciate any help. Thanks in advance
Solved. The problem was in the char array format of the IP to deliver the packet. I defined it as a 4 char array, but it should be defined as a text char array:
char link_IP[] = "192.168.1.3"; //correct !!
char link_IP[] = {192, 168, 1, 3}; // Wrong
I am trying to access a PHP file in my server with an Arduino and the Ethernet shield. This file captures the URL parameters "Sensor" and "Value" and stores the read data into a database.
This is my code:
#include <SPI.h>
#include <Ethernet.h>
EthernetClient client;
byte MACaddress[] = {0xDE,0xAD,0xBE,0xEF,0xFE,0xED};
byte IPaddress[] = {10,0,0,178};
byte DNSserverIPaddress[] = {4,4,4,4};
byte gatewayIPaddress[] = { 10, 0, 0, 100 };
byte subnetMask[] = { 255, 255, 255, 0 };
char serverName[] = "log.server.com";
void setup() {
Serial.begin(9600);
Ethernet.begin(MACaddress, IPaddress, DNSserverIPaddress, gatewayIPaddress, subnetMask);
}
void loop()
{
delay (5000);
Serial.println("connecting to server...");
client.connect(serverName, 80);
Serial.println("making HTTP request...");
client.println("GET /logger.php?sensor=temp&value=19 HTTP/1.1");
client.println("HOST: log.server.com");
client.println();
}
After uploading this code to my Arduino Mega + Ethernet shield, nothing changes in my database...
What is wrong?
Well, first you should add a condition check to know if the Arduino think it worked or not:
if (client.connect(...)) {
/* Stuff you do on success */
}
else {
Serial.println("failure! :-(")
}
If it does print failure! you got a network configuration problem on the Arduino side. If it does work, the problem is after the Arduino.
Then try opening a server with nc -kl 42000 and change the port you connect to on 42000 in the Arduino sketch, to be sure whether the network connection works.
If it does work, then you've got a problem on your host side (the webserver), if it does not, you may have a problem on the network between the Arduino and the host.
You should then try to connect to a server's IP address instead of a fully qualified domain name (FQDN). If that works, it may be the DNS server that is unreachable, and you should try to use 8.8.8.8 instead (or your local network's DNS server).
Also check that the IP address you're using is indeed free of use (and not assigned by a DHCP or used by another computer), as well as the MAC address is really unused... (addresses like {0xDE,0xAD,0xBE,0xEF,0xFE,0xED} tend to be used a lot in hacks...).
My opinion, is that your bug is the DNS server that is unreachable, as there's no DNS resolver opened on 4.4.4.4.
I want to use libpcap to capture packets
but since the length of ethernet header or 802.11 header may vary
and the length of IP header may also vary,
how can I determine the starting byte(pointer) of the IP Header and TCP header
besides, how to distinguish whether a packet is a pure IP packet, TCP packet or UDP packet?
are there any APIs or ways to do this?
thanks!
When you're using libpcap, you can determine the size of link layer header, either by directly looking at the pcap file header (for offline captures) pcap_file_header.linktype or (for live and offline captures) from a call to pcap_datalink(). Most of the time this will be LINKTYPE_ETHERNET. To ensure a packet is IPv4, you can cast into an Ethernet header and check to ensure the ethertype is ETHERTYPE_IP (make sure you wrap it inside of ntohs(). I usually apply bpf filters to my pcap instantiations so I never worry about that stuff. To check the higher layer protocols however and assuming you're using pcap_dispatch(), you can write a callback as per the following: (the libnet library is still useful for its wide array of portable packet structures):
#include <libnet.h>
#include <pcap.h>
void
process_packet(u_char *user, const struct pcap_pkthdr *header, const u_char *packet)
{
struct libnet_ipv4_hdr *ip;
struct libnet_udp_hdr *tcp;
uint16_t ip_hl, udp_hl, header_cruft;
ip = (struct libnet_ipv4_hdr *)(packet + LIBNET_ETH_H);
ip_hl = ip->ip_hl << 2;
switch (ip->ip_p)
{
case IPPROTO_UDP:
udp = (struct libnet_udp_hdr *)(packet + LIBNET_ETH_H + ip_hl);
udp_hl = tcp->th_off << 2;
header_cruft = LIBNET_ETH_H + ip_hl + tcp_hl;
break;
case IPPROTO_TCP:
/** you get the idea */
break;
default:
break;
}
I am trying to verify the Ethernet devices on a device are working correctly. I'm running the command:
ifconfig("interfaceName dhcp")
for each ethernet interface.
What I would also like to do is verify that each device got an ip address as well. I know I can just run 'ifconfig' by itself and look at the output, but I'm writing automated test code. So is there a function that can return the ip address of a specific interface in VxWorks?
I believe ifAddrGet() in ifLib.h may be what you're looking for. The first argument takes an interface name and the second argument takes a buffer, into which the address will be returned.
I haven't tested the following on an actual target, but it should be a start toward what you need:
#include <stdlib.h>
#include <stdio.h>
#include "inetLib.h"
#include "ifLib.h"
void print_if_address (void);
void print_if_address ()
{
char if_name[] = "dhcp";
char ip_address[INET_ADDR_LEN] = {0};
ifAddrGet (if_name, ip_address);
printf ("%s\n", ip_address);
}