ethernet difficulties

12 Jul 2012

I'm trying to use an mbed 1768 to interface between a load cell and excel using visual basic. I'm using the mbed to make a decision based on the information coming form the load cell. At this point, I think the details are irrelevant, I'm just having trouble getting everything to talk.

I'm trying to use ethernet. I have a standard household RJ45 jack wired into the RD+/- and TD +/- terminals of the mbed.

I've used the ethsnif program I found in the cookbook. It compiles OK, runs fine, and returns the information on Teraterm connected through the serial/USB port. That's great, but I want to use the ethernet. I've read the information regarding EthernetNetIf and can't get that program to compile.

From a big picture point of view, my understanding at this point is that I need to set up a program to tell my mbed what it's IP address is. It will then listen on the ethernet port for information addressed to it. Once I have that resolved, I can plug the load cell signal into an analog in pin on the mbed and configure my program to interpret that.

I have two network cards in my PC. The first is configured for the school network to provide internet, email, etc. The second is dedicated to my research/robot work. If I go to a command prompt and type ipconfig, it returns the information about both network cards, but never about the devices connected to them. I can ping the two controllers used for my robot from the command prompt, but not the mbed (probably because I'm not setting the IP address correctly).

I have this compilation of code that I cobbled together from things I found in the cookbook:

include "mbed.h"
#include "EthernetNetIf.h"                            

DigitalOut myled(LED1);
Serial pc(p9, p10); 
EthernetNetIf eth(
  IpAddr(192,168,175,31),     //IP Address
  IpAddr(255,255,0,0),      //Network Mask
  IpAddr(1,1,1,1),          //Gateway           //192.168.175.1
  IpAddr(1,1,1,1)              //DNS               //129.175.225.12
);

int main() {
    pc.baud(9600);
    myled=1;
    EthernetErr ethErr = eth.setup();
    if(ethErr)
    {
        pc.printf("Error %d in setup.\n\r", ethErr);
        return -1;
    }
    pc.printf("Setup OK\n\r");
    IpAddr ip = eth.getIp();
    pc.printf("Addresse IP local: %d.%d.%d.%d\r\n", ip[0], ip[1], ip[2], ip[3]); 

    while (1) {
        Net::poll();
    }
}

This code will compile ok. With it running, I try to ping the mbed at 192.168.175.31 and get no response. This is the output from the mbed to Teraterm when I reset the mbed with this program [..\fwk\if\eth\EthernetNetIf.cpp:setup@86] HW Addr is : 00:02:f7:f0:c5:4f. [..\fwk\if\eth\EthernetNetIf.cpp:setup@142] Connected, IP : 192.168.175.31

I'm sure it's obvious, but I'm new to programming and probably know just enough to be dangerous. You won't be insulting my intelligence if you start with basic information. I'm all ears! Who can help me?

12 Jun 2012

I'm not an expert but I think you need to look at how you setup the second ethernet port and the network connected to it. How did you work out the IP address etc for your mbed system? I plug mine into an existing network and it gets its own address with DHCP where the router is at 192.168.0.1 the DHCP will give an address starting 192.168.0.x; in my case the last digit is 150 due to my router setup.

Is there a way to connect it to your main school network with DHCP instead? Else read up on local networks.

11 Jul 2012

I have significantly changed my program using the vast majority of another bit of code I found on here, known as EthernetTester. Thank you Michael Wei. I altered the code based on the comments so I could use my static IP.

I have further modified the code to provide an analog in on p17 using a variable resistor. I then perform a printf command so show the value of the variable resistor on the webpage that loads with the rest of the message proved in the EthernetTester code. Most of the changes I made have commented lines stating when something was added or changed.

In this way, I know the code works. I know the ethernet connection works. It still doesn't do what I want to do though. I want to be able to use excel and visual basic to read the value of the variable resistor. I want to be able to store a sequence of the values of that variable resistor over time.

I think the mBed code is ok, but it is posted below for your perusal. I think my problem lies with my lack of experience with vb code. Can anyone help me with this?

/Ethernet Tester
//1545 22JUN2012, talks on serial, communicates through ethernet to explorer window, responds to ping
//1450 27JUN2012 TCP-IP connection dynamically updates with new ADC values.  

#include "mbed.h"
#include "lwip/opt.h"
#include "lwip/stats.h"
#include "lwip/sys.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/dns.h"
#include "lwip/dhcp.h"
#include "lwip/init.h"
#include "lwip/netif.h"
#include "netif/etharp.h"
#include "netif/loopif.h"
#include "device.h"

Ethernet ethernet;
DigitalOut ledLink(p30);
DigitalOut ledActivity(p29);
DigitalOut ledStage0 (LED1);
DigitalOut ledStage1 (LED2);
DigitalOut ledStage2 (LED3);
DigitalOut ledTCP80 (LED4);
float time1;//added 6/26/12 1145
float time2; // added 6/26/12 1145
AnalogIn Ain(p17);   //added 6/26/12 1145
//const char *ADCdata; //added 6/26/12 1145  comment 6/27/12
const char *data;
float ADCdata;      //add 6/27/12
int testing;        //add 6/29/12
Serial pc(USBTX, USBRX);
volatile char stage = 0;

Ticker stage_blinker;

struct netif    netif_data;

const char testPage[] = "HTTP/1.1 200 OK\r\n"
                        "Content-Type: text/html\r\n"
                        "Connection: Close\r\n\r\n"
                        "<html>"
                        "<head>"
                        "<title>mbed test page</title>"
                        "<style type='text/css'>"
                        "body{font-family:'Arial, sans-serif', sans-serif;font-size:.8em;background-color:#fff;}"
                        "</style>"
                        "</head>"
                        "<body>%s</body></html>\r\n\r\n";

char buffer[1024];
char temp[1024];
err_t recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
    struct netif   *netif = &netif_data;
    ledTCP80 = true;
    printf("TCP callback from %d.%d.%d.%d\r\n", ip4_addr1(&(pcb->remote_ip)),ip4_addr2(&(pcb->remote_ip)),ip4_addr3(&(pcb->remote_ip)),ip4_addr4(&(pcb->remote_ip)));
    char *data;
    /* Check if status is ok and data is arrived. */
    if (err == ERR_OK && p != NULL) {
        /* Inform TCP that we have taken the data. */
        tcp_recved(pcb, p->tot_len);
        data = static_cast<char *>(p->payload);
        /* If the data is a GET request we can handle it. */
        if (strncmp(data, "GET ", 4) == 0) {
        printf("Handling GET request...\r\n");
        printf("Request:\r\n%s\r\n", data);
        ADCdata=Ain;                                    //new line 6/27/12
        *data=5;                                        //added 6/29/12
        
        //generate the test page
        time_t seconds = time(NULL);
        sprintf(temp,     "<h1>Congratulations!</h1>If you can see this page, your mbed is working properly."
                          "<h2>mbed Configuration</h2>"
                          "mbed RTC time:%s<br/>"
                          "mbed HW address: %02x:%02x:%02x:%02x:%02x:%02x<br/>"
                          "mbed IP Address: %s<br/>"
                          "ADCdata= %f\n\r",                          //new line 6/27/12  
        
        ctime(&seconds),
        (char*) netif->hwaddr[0],
        (char*) netif->hwaddr[1],
        (char*) netif->hwaddr[2],
        (char*) netif->hwaddr[3],
        (char*) netif->hwaddr[4],
        (char*) netif->hwaddr[5],
        inet_ntoa(*(struct in_addr*)&(netif->ip_addr)),
        ADCdata);                       //added 6/27/12
        testing=ethernet.write(data,4);         //added 6/29/12
        ledActivity=ethernet.send();    //added 6/29/12
        wait(1);                        //added 6/29/12
        
        
        
        printf("how many bytes were written? %d\n\r", testing);
        sprintf(buffer, testPage, temp);
            if (tcp_write(pcb, (void *)buffer, strlen(buffer), 1) == ERR_OK) {
            tcp_output(pcb);
            printf("Closing connection...\r\n");
            tcp_close(pcb);
            }
        }
        else
        {
            printf("Non GET request...\r\nRequest:\r\n%s\r\n", data);
        }
        
        pbuf_free(p);
    }
    
     else {
            /* No data arrived */
            /* That means the client closes the connection and sent us a packet with FIN flag set to 1. */
            /* We have to cleanup and destroy out TCPConnection. */
             printf("Connection closed by client.\r\n");
            pbuf_free(p);
        }
    /* Don't panic! Everything is fine. */
    ledTCP80 = false;
    return ERR_OK;
}
/* Accept an incomming call on the registered port */
err_t accept_callback(void *arg, struct tcp_pcb *npcb, err_t err) {
    LWIP_UNUSED_ARG(arg);
    /* Subscribe a receive callback function */
    tcp_recv(npcb, &recv_callback);
    /* Don't panic! Everything is fine. */
    return ERR_OK;
}

void stageblinker()
{
    switch (stage)
    {
        case 0:
        ledStage0 = !ledStage0;
        ledStage1 = false;
        ledStage2 = false;
        break;
        case 1:
        ledStage0 = true;
        ledStage1 = !ledStage1;
        ledStage2 = false;
        break;
        case 2:
        ledStage0 = true;
        ledStage1 = true;
        ledStage2 = true;
        stage_blinker.detach();
        break;
    }
}

int main() {
    printf("mBed Ethernet Tester 1.0\r\nStarting Up...\r\n");
    stage = 0;
    struct netif   *netif = &netif_data;
    struct ip_addr  ipaddr;
    struct ip_addr  netmask;
    struct ip_addr  gateway;
    Ticker tickFast, tickSlow, tickARP, eth_tick, dns_tick, dhcp_coarse, dhcp_fine;
    stage_blinker.attach_us(&stageblinker, 1000*500);
    
    char *hostname = "my-mbed";
    
    printf("Configuring device for DHCP...\r\n");
   
    //Start Network with DHCP 
    IP4_ADDR(&netmask, 255,255,255,0); //changed from 255.255.255.255
    IP4_ADDR(&gateway, 0,0,0,0);
    IP4_ADDR(&ipaddr, 192,168,100,2);   //changed from 0.0.0.0
    /* Initialise after configuration */
    lwip_init();
    netif->hwaddr_len = ETHARP_HWADDR_LEN;
    device_address((char *)netif->hwaddr);
    netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, device_init, ip_input);
    netif->hostname = hostname;
    netif_set_default(netif);
    
    netif_set_up(netif);    //new line to use static IP
    //dhcp_start(netif); // <-- Use DHCP
    
        /* Initialise all needed timers */
    tickARP.attach_us( &etharp_tmr,  ARP_TMR_INTERVAL  * 1000);
    tickFast.attach_us(&tcp_fasttmr, TCP_FAST_INTERVAL * 1000);
    tickSlow.attach_us(&tcp_slowtmr, TCP_SLOW_INTERVAL * 1000);
    dns_tick.attach_us(&dns_tmr, DNS_TMR_INTERVAL * 1000);
    dhcp_coarse.attach_us(&dhcp_coarse_tmr, DHCP_COARSE_TIMER_MSECS * 1000);
    dhcp_fine.attach_us(&dhcp_fine_tmr, DHCP_FINE_TIMER_MSECS * 1000);
    stage = 1;
         while (!netif_is_up(netif)) { 
         ledLink = ethernet.link();
         device_poll(); 
     } 

/*
    while (!(netif->dhcp->state == DHCP_BOUND || netif->dhcp->state == DHCP_PERMANENT))
    {
        ledLink = ethernet.link();
        device_poll();    
        //printf("Waiting for DHCP response, state = %d\r\n", netif->dhcp->state);
        //wait_ms(100);
        }
    */
    stage = 2;
            printf("Interface is up, local IP is %s\r\n", 
inet_ntoa(*(struct in_addr*)&(netif->ip_addr))); 

    printf("Starting Web Server...\r\n");

        /* Bind a function to a tcp port */
    struct tcp_pcb *pcb = tcp_new();
    if (tcp_bind(pcb, IP_ADDR_ANY, 80) == ERR_OK) {
        pcb = tcp_listen(pcb);
        tcp_accept(pcb, &accept_callback);
    }
   
    printf("Waiting for connection...\r\n");
    while(1) {
        device_poll();
        ledLink = ethernet.link();
    }
}