I am attempting to send data from my Arduino to my computer via LAN connection on port 65 of my laptop running Windows 10.
Right now, I haven't reached the data part due to my major roadblock: I cannot get the CC3000 to connect to my Python server.
The debug from the Arduino is just what you would expect if it couldn't connect, but here you go: (apparently after a while it gives up on finding my computer's IP address)
Initializing CC3000.............Initialized!
Requesting Connection to WiFi Network....Connected!
Requesting DHCP...
Failed!
Displaying Connection Details...Success!
IP Addr: 192.168.0.113
Netmask: 255.255.255.0
Gateway: 192.168.0.1
DHCPsrv: 192.168.0.1
DNSserv: 192.168.0.1
Success!
Connecting to client............
Determining IP of host...
0.0.0.0Failed!
Connecting to client............
Determining IP of host...
0.0.0.0Failed!
Connecting to client............
Determining IP of host...
0.0.0.0Failed!
Connecting to client............
Determining IP of host...
0.0.0.0Failed!
Connecting to client............
Determining IP of host...
0.0.0.0Failed!
Connecting to client............
Determining IP of host...
0.0.0.0Failed!
Connecting to client............
Determining IP of host...
0.0.0.0Failed!
Connecting to client............
Determining IP of host...
0.0.0.0Failed!
Connecting to client............
Determining IP of host...
Failed!
Failed!
Failed!
Here is my Arduino code (I have a Linksprite CC3000, but I'm using the Adafruit CC3000 library):
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include <stdlib.h>
// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin!
#define ADAFRUIT_CC3000_VBAT 5 // Apparently these can be any two pins
#define ADAFRUIT_CC3000_CS 10 // But I wouldn't change these...
// Use hardware SPI for the remaining pins (On a Mega 2560, SCK = 52, MISO = 50, and MOSI = 51)
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);
#define WLAN_SSID "ARK_TP-LINK_2.4GHz_FFBC77"
#define WLAN_PASS "AHomeRWirelessK1!"
#define WLAN_SECURITY WLAN_SEC_WPA2
String readString = String(100); //string for fetching data from address
uint32_t ip = ( 192 << 24 ) & ( 168 << 16 ) & ( 0 << 8 ) & ( 115 ); // This translates into the ip address we need
// 323223552X; 192.168.0.X
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.print(F("Initializing CC3000............."));
if (!cc3000.begin())
{
Serial.println(F("Failed! Check your wiring?"));
while(1);
}
Serial.println("Initialized!");
//Connect to the Wireless Access Point
Serial.print("Requesting Connection to WiFi Network....");
if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
Serial.println(F("Failed!"));
while(1);
}
Serial.println(F("Connected!"));
int DHCPTimeout = 0;
bool failed = false;
Serial.print(F("Requesting DHCP..."));
Serial.println("\n" + (!cc3000.checkDHCP()));
while (!cc3000.checkDHCP() && DHCPTimeout < 16)
{ //Obtain IP addeess
Serial.println("Failed!");
delay(1000);
DHCPTimeout = DHCPTimeout + 1;
if (DHCPTimeout == 15)
{
failed = true;
}
}
if (failed)
{
Serial.println("Timed Out...");
} else
{
Serial.print("Displaying Connection Details...");
while (! displayConnectionDetails())
{
Serial.println("Failed!");
delay(1000);
}
Serial.println("Success!");
}
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("Connecting to client............");
Serial.println("Determining IP of host...");
uint32_t ip;
while (!cc3000.getHostByName("name_of_LAN_PC", &ip))
{
Serial.println("Failed!");
delay(1000);
}
cc3000.printIPdotsRev(ip);
Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 65);
if (client.connected()){
Serial.println("Success!");
Serial.println("Saying hi...");
client.println("hi");
client.println("");
if (client.available()){
char c = client.read();
Serial.print(c);
}
} else{
Serial.println("Failed!");
}
client.close();
delay(1000);
}
bool displayConnectionDetails(void)
{
uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
{
//Serial.println(F("Unable to retrieve the IP Address!\r\n"));
return false;
}
else
{
Serial.print("Success!");
Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
Serial.println();
return true;
}
}
Of course, the Python code is extremely simple in comparison:
import socket
import time
import smtplib as smtp
def send_email(subject, message, to): #Send an email
fro = "unoarduino77#gmail.com"
print("Sending Email:",subject)
server = smtp.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.ehlo()
server.login(fro, "alphabetagammadelta")
header = "To:" + to + "\n" + "From: " + fro + "\n" + "Subject:" + subject + "\n"
#header for message contains to, from, and subject
msg = header + "\n" + message + " \n\n"
#formulate packet using header and message
server.sendmail(fro, to, msg)
server.close()
def createServer(): #Create a server to recieve
global sock #data from the Arduino
sock = socket.socket()
host = socket.gethostname()
print("Initializing Server")
print("Host:", host)
port = 65
print("Port:", port)
sock.bind((host, port))
#print(sock.bind((host, port)))
sock.listen(5)
while 1:
c, addr = sock.accept()
c.send("Connected!")
print("Connected to "+addr[0]+":"+str(addr[1]))
print(c.recv(1024))
createServer()
If your main objective is to establish communication from the arduino to python check out this page:
https://playground.arduino.cc/Interfacing/Python
You can communicate between your python code and Arduino via the serial Interface
Related
I am trying to implement a basic UDP socket in my code to send a string. Created an UDP server in C++ to send sort of a "hello world" and a client in Python to receive it. For this, I'm using G4G's example as base, only slightly modified:
#define PORT xxxx
void initializeUDP(int stop) {
int sockfd;
const char *hello = "Hello from server.\n";
struct sockaddr_in servaddr, cliaddr;
//Initialize Winsock
WSADATA data;
WORD version = MAKEWORD(2, 2);
int wsOk = WSAStartup(version, &data);
if (wsOk != 0) {
cout << "Cannot start Winsock! " << wsOk;
return;
}
// Creating socket and binding with address
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
if (::bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
int len;
len = sizeof(cliaddr); //len is value/result
while (globalVariableNameInPortuguese == 0) {
sendto(sockfd, (const char *)hello, 1024, 0, (const struct sockaddr *) &cliaddr, len);
}
closesocket(sockfd);
WSACleanup();
}
Also created these few lines to try to receive this string as a client in Python:
import socket
bufferSize = 1024
ip = "localhost"
port = xxxx
UDPClientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
UDPClientSocket.connect((ip, port))
while True:
message, address = UDPClientSocket.recvfrom(bufferSize)
print(message)
UDPClientSocket.close()
The C++ code executes normally but I am uncertain whether it's actually doing what it should. However, if I set the IP in the Python code as "localhost" it gets stuck in recvfrom, and if I set the IP to 0.0.0.0 it gets WinError 10049. Not sure on what I'm doing wrong and how I should proceed to actually get this string.
I have an ESP32 opening a simple TCP server and a python script accessing as client.
Things are going quite smooth, but when the ESP32 reset (e.g. after a power loss) or when no connection is made directly after powering the ESP, the client cannot connect any more.
ESP Server code, using Arduino Core(shortend):
#include <WiFi.h>
WiFiServer server(23);
void setup() {
server.begin();
}
void loop() {
WiFiClient client = server.available();
if (client) {
if (client.connected()) {
Serial.println("Client connected");
lastConnection = timeNow;
if (client.available()) {
Serial.println("Data to be read");
String line = client.readStringUntil('\n');
Serial.println(line);
}
if (timeSendWs < timeNow) {
Serial.println("Sending data");
String msg = notifyClients(); //notifyClients() build the message that is to be send
char *cmsg = &msg[0];
client.write(cmsg);
timeSendWs = timeNow + TIME_SEND_WS;
}
}
Serial.println("Disconnecting");
client.stop();
}
if (lastConnection < timeNow - 2 * TIME_SEND_WS) {
Serial.println("Connection interrupted for too long");
client.stop();
Stopping(); //Some action that needs to taken, when not connection could be established for some time
lastConnection = timeNow;
}
}
Python script
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
s.connect(('192.168.2.251', 23))
s.sendall('hi\n'.encode()) # Include \n to ensure faster processing
data = []
while True:
chunk = s.recv(1024)
if not chunk: break # When the other side closes the socket, chunk = ''
data.append(chunk.decode())
all_data = ''.join(data)
if len(all_data) > 0:
print(all_data)
except OSError as e:
print(e)
s.close()
time.sleep(0.1)
The errors I get on python side are either "timeout" or "[Errno 64] Host is down" and just before reconnecting "[Errno 61] Connection refused"
Hello l am new to BSD Socket API programming. I followed the UDP client example on the Wikipedia (https://en.wikipedia.org/wiki/Berkeley_sockets) and l am encountering a strange issue. The packets arrive at my server, but the message inside is cut off. I am looking for the terminology for this problem, and a clue to resolve this issue. Thank you for the assistance.
C Function:
void udp_client_task() {
while(1) {
int sock; struct sockaddr_in sa; char buffer[200];
strcpy(buffer,"My World NEO! This is My World!");
/* create an Internet, datagram, socket using UDP */
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1) {
/* if socket failed to initialize, exit */
break;
}
/* Zero out socket address */
memset(&sa, 0, sizeof sa);
/* The address is IPv4 */
sa.sin_family = AF_INET;
/* IPv4 addresses is a uint32_t, convert octets to the appropriate value */
sa.sin_addr.s_addr = inet_addr("192.168.0.5");
/* sockets are unsigned shorts, htons(x) ensures x is in network byte order */
sa.sin_port = htons(139);
bytes_sent = sendto(sock, buffer, strlen(buffer), 0,(struct sockaddr*)&sa, sizeof sa);
// osDelay(500);
close(sock); /* close the socket */
}
Python UDP Server:
import socket
from datetime import datetime
class UDP_Server():
def __init__(self, single_group, port_receive):
self.single_group = single_group
self.port_receive = port_receive
def configure_receive_server(self):
# Define the buffer size for this function
size_buffer = 1024
# Print start of function
msg = 'UDP Receive Inputs: Single Group - {0} ; Port (Receive From) - {1} ; Buffer Size - {2}'.format(self.single_group, self.port_receive, size_buffer)
print(msg)
# Open a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
print("Socket created...")
# Allow port reuse
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print("Socket allowed reuse...")
# Bind IP Address to Port
print("Binding the IP: {0}".format(self.single_group))
sock.bind((self.single_group, self.port_receive))
while True:
print("------ New Loop ------")
# Receive the client packet along with the address it is coming from
message, address = sock.recvfrom(1024)
print("{0}".format(datetime.now().strftime("%Y-%m-%d_%H:%M:%S")))
msg = 'UDP message received from address - {0} ; \nMessage - {1} ; \nMessage Length - {2}'.format(address, message, len(message))
print(msg)
if __name__ == '__main__':
# Define constants
UDP_IP = "192.168.0.5"
# UDP_group = "192.168.0.5"
port_receive_tlm = 139
# port_receive_tlm = 139
# Initialize the class
commander = UDP_Server(single_group=UDP_IP,
port_receive=port_receive_tlm)
# Listen for a response
# NOTE: This will exit after a certain number of attempts
commander.configure_receive_server()
I am trying to create a socket program that communicate with client android device to simulate clicks on it, so far I managed to set up and run the TCP server code successfully on Python using the code below.
import socket
import time
HOST = '192.168.1.243'
PORT = 4000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
while True:
time.sleep(1)
conn.sendall(b'a 925 1725\n') //Click 1
time.sleep(1)
conn.sendall(b'a 220 2100\n') //Click 2
After some research, I am able to produce the C code for TCP server to bind host and port, listen for clients and accept clients.
#include<stdio.h>
#include<time.h>
#include<unistd.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<string.h>
#include<arpa/inet.h>
#define PORT 4000
int main(int argc, char const*argv[])
{
int createsocket, phone_socket;
struct sockaddr_in server;//Declare structure to connect to a remote server
int opt = 1;
int addrlen = sizeof(server);
char buffer[1024] = {0};
ssize_t sendto(int createsocket, const void *buf, size_t len, int flags, const struct
sockaddr *dest_addr, socklen_t addrlen);
createsocket = socket(AF_INET, SOCK_STREAM, 0); //To create socket
if (createsocket == -1){
printf("Error creating socket");
}
//Assign structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("10.10.10.10"); //Assign host
server.sin_port = htons( PORT ); //Assign port
//Bind host and phone
if (bind(createsocket, (struct sockaddr *)&server, sizeof(server))<0){
printf("Bind error\n");
return 1;
}
else
printf("Bind Connected\n");
//Ready to receive connections
if (listen(createsocket, 5) < 0){
printf("Listening error\n");
return 1;
}
else
printf("Listening\n");
//Connection received, pending accept
if((phone_socket = accept(createsocket, (struct sockaddr *)&server,(socklen_t*)&addrlen)< 0){
printf("Failed to accept\n");
return 1;
}
else
printf("Accepted device\n");
while(1){
sleep(1); //One second delay
printf("click\n"); //Supposed click command
}
}
Anybody knows how to convert the python line conn.sendall(b'a 925 1725\n') for clicking into C?
Thank you for your help!
Are you trying to change into C from Python or something else? I might be able to help with a bit more explanation of what your goal is other than clicking into C.
I am working in a C program with sockets. I found a proxy python script which is working with my program:
import threading
import serial
import socket
def setup():
"""
This function sets up the variables needed, including the serial port,
and it's speed/port settings, listening socket, and localhost adddress.
"""
global clisock, cliaddr, svrsock, ser
# Change this to the COM port your XBee Cellular module is using. On
# Linux, this will be /dev/ttyUSB#
comport = '/dev/ttyAMA0'
# This is the default serial communication speed of the XBee Cellular
# module
comspeed = 9600
buffer_size = 4096 # Default receive size in bytes
debug_on = 0 # Enables printing of debug messages
toval = None # Timeout value for serial port below
# Serial port object for XBCell modem
ser = serial.Serial(comport,comspeed,timeout=toval)
# Listening socket (accepts incoming connection)
svrsock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# Allow address reuse on socket (eliminates some restart errors)
svrsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
clisock = None
cliaddr = None # These are first defined before thread creation
addrtuple = ('localhost', 1881) # Address tuple for localhost
# Binds server socket to localhost (allows client program connection)
svrsock.bind(addrtuple)
svrsock.listen(1) # Allow (1) connection
def ComReaderThread():
"""
This thread listens on the defined serial port object ('ser') for data
from the modem, and upon receipt, sends it out to the client over the
client socket ('clisock').
"""
global clisock
while (1):
resp = ser.read() ## Read any available data from serial port
print("Received {} bytes from modem.".format(len(resp)))
clisock.sendall(resp) # Send RXd data out on client socket
print("Sent {} byte payload out socket to client.".format(len(resp)))
def SockReaderThread():
"""
This thread listens to the MQTT client's socket and upon receiving a
payload, it sends this data out on the defined serial port ('ser') to the
modem for transmission.
"""
global clisock
while (1):
data = clisock.recv(4096) # RX data from client socket
# If the RECV call returns 0 bytes, the socket has closed
if (len(data) == 0):
print("ERROR - socket has closed. Exiting socket reader thread.")
return 1 # Exit the thread to avoid a loop of 0-byte receptions
else:
print("Received {} bytes from client via socket.".format(len(data)))
print("Sending payload to modem...")
bytes_wr = ser.write(data) # Write payload to modem via UART/serial
print("Wrote {} bytes to modem".format(bytes_wr))
def main():
setup() # Setup the serial port and socket
global clisock, svrsock
if (not clisock): # Accept a connection on 'svrsock' to open 'clisock'
print("Awaiting ACCEPT on server sock...")
(clisock,cliaddr) = svrsock.accept() # Accept an incoming connection
print("Connection accepted on socket")
# Make thread for ComReader
comthread = threading.Thread(target=ComReaderThread)
comthread.start() # Start the thread
# Make thread for SockReader
sockthread = threading.Thread(target=SockReaderThread)
sockthread.start() # Start the thread
main()
I tried to do the same proxy script in C
#include "project.h"
#include <sys/socket.h>
#include <arpa/inet.h>
int fd,baudrate=9600,sock,new_socket;
struct sockaddr_in serv_addr, client;
int setup(){
int opt=1;
sock=0;
if(wiringPiSetup() <0) return 1;
if((fd=serialOpen("/dev/ttyAMA0",baudrate))<0) return 1;
printf("Serial communication opened \n");
fflush(stdout);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
printf("\n Socket creation error \n");
return -1;
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR , &opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(1881);
int addrlen = sizeof(struct sockaddr_in);
if (bind(sock, (struct sockaddr *)&serv_addr, addrlen)<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(sock, 1) <0)
{
perror("listen");
exit(EXIT_FAILURE);
}
printf("1\n");
addrlen=sizeof(struct sockaddr_in);
socklen_t sin_size=sizeof(struct sockaddr_in);
if ((new_socket = accept(sock, (struct sockaddr *)&client, &sin_size)) < 0)
{
perror("accept");
exit(EXIT_FAILURE);
}
char *client_ip = inet_ntoa(client.sin_addr);
printf("Accepted new connection from a client %s:%d\n", client_ip, ntohs(client.sin_port));
printf("1\n");
return 0;
}
PI_THREAD(socketRead){
int valread;
char buffer[4096]={0};
printf("hola %i\n",new_socket);
//Nos mantenemos a la escucha
for(;;){
//memset(buffer,0,sizeof(buffer));
//valread = recv( new_socket, buffer, 1024,0);
while((valread = read(new_socket,buffer,sizeof(buffer)-1))>0){
/*if ( valread < 0 ) {
printf ( "An error occured during the receive procedure \n" ) ;
return 0 ;
}*/
buffer[valread]=0;
printf("buffer %s\n",buffer);
write(fd,buffer,strlen(buffer));
}
}
}
PI_THREAD(uartRead){
int valread;
char buffer[4096]={0};
//Nos mantenemos a la escucha
for(;;){
//memset(buffer,0,sizeof(buffer));
valread = read( fd, buffer, sizeof(buffer));
//valread = read(new_socket,buffer,4096);
//send( new_socket, buffer,4096,0);
write(new_socket,buffer,sizeof(buffer));
printf("recibido\n");
}
}
int main(){
setup();
printf("adios %i\n",new_socket);
/* Thread creation */
piThreadCreate (socketRead);
piThreadCreate (uartRead);
for(;;){}
return 0;
}
I have not found differences between both programs, so my question is if there are any differences between Python and C libraries. With Python I am allow to see read the messages but in C I only receive 0x10 and 0x11. So, are there any differences between libraries or is something with my C script?
PI_THREAD(uartRead){
...
char buffer[4096]={0};
...
valread = read( fd, buffer, sizeof(buffer));
...
write(new_socket,buffer,sizeof(buffer));
In this code you read valread byte from the serial line but you always write 4096 byte (sizeof(buffer)). This means you send not only the data from the serial line but lots of junk data which are in the buffer.
The problem is thus not the difference between sockets in Python and C but just a bug in the C program.