create local network

Discussion about any of the included sketches (i.e. WebServer), or user-generated applications.

Re: create local network

Postby GregEigsti » Fri May 28, 2010 10:06 pm

Disclaimer - the comments below may seem a little harsh and I hope that you take them in the right way. I could say nothing or I could point out the "issues" and maybe help you learn. I'm choosing the latter. I recommend investing some time to study and learn the C language a little better - you will be a lot less frustrated and make better/quicker progress (besides learning a valuable skill).

Your light() function with extra newlines removed:
Code: Select all
void light() {
     for(i = 0; i < 100 ; i++) {
        pulse = 3000;
        digitalWrite(LED, HIGH);
        delay(pulse);
        digitalWrite(LED, LOW);   
    } 
}

the value: 300 is Milliseconds not seconds so there should be plenty of time for the server to be serviced.

The code that you provided sets the "pulse" variable to 3000 which is taken as milliseconds in the call to delay() - 3000 ms is 3 seconds; you are then looping 100 times in your for loop calling delay(3000) each time. 3 seconds times 100 iterations of the for loop means you are sleeping 300 seconds. Not servicing the WiShield for 300 seconds is going to asplode your app/connectivity.
I just want to return true to the function sendMyPage so the server can keep running.

The light() function returns no value and you are not checking what it is returning so I'm assuming what you meant to say is that that you "want to return true from sendMyPage()".
I tried setting sendMyPage to a char function instead of a boolean but it didn't allow it.

Right, because sendMyPage() is a callback function and the code that calls it is looking for that function to match a specific "signature". If you change the return type of your sendMyPage() function then it won't match the expected signature and your build will fail (or it should fail to build anyway).
when the code gets into light() the function sendMyPage doesn't return anything to WiServer.init(sendMyPage)

The very next statement after your call to light() is "return true;" - the assertion that "sendMyPage doesn't return anything" is incorrect - it clearly returns true in this case. Also it is not correct to say that you are not (or are) returning anything to WiServer.init(sendMyPage); WiServer.init() merely provides WiServer with the address of your callback function (sendMyPage). When sendMyPage() returns it is returning to the location in the WiServer code that called it - not WiServer.init().
and that's why I can't switch to any other function.

I'm not sure what this means but I don't think that it really matters as it is not a correct diagnoses.

Did you try commenting out the light() function as I suggested to see if things started working? The problem here is that you are killing your connection, and therefore your app, by sleeping too long.

I also noticed that you have your "wireless_mode" set to adhoc rather than infrastructure - is this really what you wanted to do?

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 1075
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)
  • Website

Re: create local network

Postby domimedia » Fri May 28, 2010 10:46 pm

Hello again,

Disclaimer - the comments below may seem a little harsh and I hope that you take them in the right way.


No worries! I took them the right way. You've been really helpful. thank you.

Code: Select all
The code that you provided sets the "pulse" variable to 3000 which is taken as milliseconds in the call to delay() - 3000 ms is 3 seconds; you are then looping 100 times in your for loop calling delay(3000) each time. 3 seconds times 100 iterations of the for loop means you are sleeping 300 seconds. Not servicing the WiShield for 300 seconds is going to asplode your app/connectivity.


I see what you mean now, you are right.

The WiShield connection always worked but jut stop responding when I enter to the loop. I did tried commenting the light() function and it worked as usual but I need the light() function because I got the WiShield to control that function wireless.

Code: Select all
I also noticed that you have your "wireless_mode" set to adhoc rather than infrastructure - is this really what you wanted to do?


Yes, I want to use this method, It works fine for me.

I guess what I really need is you to suggest a way that I can do to execute a never ending animation with a for loop without loosing my connection.

I really appreciate your time in this post Greg! Thank you man!
domimedia
 
Posts: 9
Joined: Wed May 26, 2010 9:01 pm

Re: create local network

Postby GregEigsti » Sat May 29, 2010 12:21 am

Well now that we are past introductions I can help you run your "animation" in a "non-destructive" manner! But we had to get past the problems before we could move on. I'm suddenly feeling a bit sadistic after typing that :D I pointed out the adhoc thing because the vast majority of user's apps are run in infrastructure mode - just wanted to make sure.

So my answer, and I am still grappling with the best way to explain it, is going to make use of a timer based ISR (interrupt service routine); likely using MSTimer2. You need to be careful using ISRs though - you need to do very little work in them as they block all other execution just like your loop does. However they can be more flexible and will allow you to achieve your goal without gumming up the works (or blocking).

So yes, it can be done easily and I'll help get you going. Just need to ponder on how I should explain it - without writing your app for you ;)

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 1075
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)
  • Website

Re: create local network

Postby domimedia » Sat May 29, 2010 1:13 am

Interesting!

I have installed the library MsTimer2 and added this to my setup() :

Code: Select all
MsTimer2::set(10, WiServer.server_task);
MsTimer2::start();


and removed this from my loop:

Code: Select all
WiServer.server_task();
delay(10);


But I get this when I try to test it:

Code: Select all
In function 'void setup()':
error: argument of type 'void (Server::)()' does not match 'void (*)()


What is the right way to use this then?

Thanks!
domimedia
 
Posts: 9
Joined: Wed May 26, 2010 9:01 pm

Re: create local network

Postby GregEigsti » Sat May 29, 2010 3:18 am

WiServer.server_task() is not the correct type of function to pass into MsTimer2::set() and that is why you are getting build errors. You need to take it out of the MSTimer2 call and put it back into your loop() function. For an example of MSTimer2 use take a look at this thread. You may want to reconsider setting MSTimer2 to fire at a 10 millisecond interval - but I think you will understand why later.

I stated previously:
You need to be careful using ISRs though - you need to do very little work in them as they block all other execution just like your loop does.

WiServer.server_task() is a pretty heavy weight function - when I said you need to do very little work in an ISR I meant you can set a global boolean value and no more. For example my ISR function looks like:
Code: Select all
//MsTimer2 timer ISR
void timerISR() {
   intTimer = true;
}


The basic idea is you utilize MSTimer2 to fire at an interval; when it fires your ISR function is called (e.g. timerISR() above). In your ISR you do some extremely light operation (such as set intTimer to true as in the above ISR) and then in your loop() function you look at the value of intTimer and do the heavy lifting there. Basically you are using MSTimer2 to signal your loop() function to do something via your ISR function. You can structure things a bit differently but this is the most fool proof and safest way to go.

So in your case you are toggling an LED in three second intervals 100 times. So you might consider using a value of 3000 ms (or three seconds) for MSTimer2; this way your boolean will get set every three seconds. Your loop() function looks for that boolean to be set and then toggles your LED. You'll need to utilize a few global variables to keep track of your current state as well.

This is roughly what you want; there are some obvious things missing (like all of the WiShield goop) but it should give you the idea. That said I have not attempted to build/run this code. On second thought, I am pretty darned tired so there could be issues here; nothing major but just things that my fried brain is glossing over.
Code: Select all
//handy defines
#define ANIMATEMS 3000
#define ANIMATECOUNT 100

//global data
volatile boolean intTimer;
boolean ledPowered;
byte animateCount;

//MsTimer2 timer ISR
void timerISR() {
   intTimer = true;
}

void setup()
{
   //set up global state data
   intTimer = false;
   ledPowered = false;
   animateCount = ANIMATECOUNT;

   //setup the MSTimer2 timerISR to fire every three seconds
   MsTimer2::set(ANIMATEMS, timerISR);
   MsTimer2::start();
}

void loop()
{
   if(true == intTimer) {
      //reset intTimer to false
      intTimer = false;
      //if we have animated less than ANIMATECOUNT (100) times continue animating
      //otherwise do nothing
      if(ANIMATECOUNT > animateCount) {
         animateCount++;
         //toggle the LED
         ledPowered = !ledPowered;
         digitalWrite(LED, true == ledPowered ? HIGH : LOW);
      }
   }

   // do other things including servicing the WiShield
   WiServer.server_task();
}

boolean sendMyPage(char* URL) {     
   // Check if the requested URL matches "/"
   if (strcmp(URL, "/LIGHT") == 0) {
      animateCount = 0;
      return true;
   }
   return false;
}   


BTW - "true == ledPowered ? HIGH : LOW" is a ternary expression which is a compact way to write a simple if/else statement.

Edit - cleaned the code up a bit and fixed a couple issues; added #defines to make life easier. Also thinking that you could start and stop MSTimer2 when appropriate (e.g. start it when animation is supposed to occur, stop it when they are not). Might be a slightly more efficient way to go but I'll leave that as an exercise to the reader :D

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 1075
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)
  • Website

Re: create local network

Postby domimedia » Mon May 31, 2010 12:28 pm

Hello,


I got it!

The MsTimer2 was not necessary. It was a matter of calling the function in the loop() and animate from there, that way the server was running many times per second. The for() was not necessary. It was really a matter of logic and service the server as Greg said.

Thank you Greg.

I will post my project soon. It consist on controlling an animation with an iPhone using an E ink display.

Regards,

Alexander Castillo
domimedia
 
Posts: 9
Joined: Wed May 26, 2010 9:01 pm

Re: create local network

Postby domimedia » Mon May 31, 2010 1:18 pm

:( new problem:

when trying to use the WiShield with a 9v battery it drains in 30 minutes. I used a new battery and the same happened.

It seems this is a common problem:

viewtopic.php?f=23&t=326&start=0

Is there a solution for this?
domimedia
 
Posts: 9
Joined: Wed May 26, 2010 9:01 pm

Re: create local network

Postby DaveyJonze » Thu Dec 02, 2010 6:03 pm

Hello all,

I have been playing with iphoneczar's code to control an LED with an iphone over an ADHOC network. I am able to pull up the led on/off page and turn on and off the LED on my arduino, but then after about 15 seconds I can no longer load the page.

Here is the code, although it is the same as the code posted previously in this thread:
Code: Select all
/*
    * A simple sketch that uses WiServer to serve a web page
    */


    #include <WiServer.h>

    #define WIRELESS_MODE_INFRA   1
    #define WIRELESS_MODE_ADHOC   2
      int ledPin =  7;    // LED connected to digital pin 7

    // Wireless configuration parameters ----------------------------------------
    unsigned char local_ip[] = {192,168,1,152};   // IP address of WiShield
    unsigned char gateway_ip[] = {192,168,1,1};   // router or gateway IP address
    unsigned char subnet_mask[] = {255,255,255,0};   // subnet mask for the local network
    const prog_char ssid[] PROGMEM = {"AYEFON.COM"};      // max 32 bytes

    unsigned char security_type = 0;   // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2

    // WPA/WPA2 passphrase
    const prog_char security_passphrase[] PROGMEM = {"1234567"};   // max 64 characters

    // WEP 128-bit keys
    // sample HEX keys
    prog_uchar wep_keys[] PROGMEM = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,   // Key 0
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // Key 1
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // Key 2
                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // Key 3
                };

    // setup the wireless mode
    // infrastructure - connect to AP
    // adhoc - connect to another WiFi device
    //unsigned char wireless_mode = WIRELESS_MODE_INFRA;
    unsigned char wireless_mode = WIRELESS_MODE_ADHOC;

    unsigned char ssid_len;
    unsigned char security_passphrase_len;
    // End of wireless configuration parameters ----------------------------------------


    // This is our page serving function that generates web pages
    boolean sendMyPage(char* URL) {
     
        // Check if the requested URL matches "/"
        if (strcmp(URL, "/on") == 0) {
            digitalWrite(ledPin, HIGH);   // set the LED on
            // Use WiServer's print and println functions to write out t\he page content
            WiServer.print("<html><body><meta name=\"viewport\" content=\"width=device-width, user-scalable=no\" />");
            WiServer.print("<table width=\"320\"><tr><td>");
            WiServer.print("<a href=\"off\">Hello I'm on! Turn me off.</a></td></tr>");
            WiServer.print("</table></body></html>");
           
            // URL was recognized
            return true;
        }
        if (strcmp(URL, "/off") == 0) {
            digitalWrite(ledPin, LOW);   // set the LED off
            // Use WiServer's print and println functions to write out the page content
            WiServer.print("<html><body><meta name=\"viewport\" content=\"width=device-width, user-scalable=no\" />");
            WiServer.print("<table width=\"320\"><tr><td>");
            WiServer.print("<a href=\"on\">Goodbye I'm off! Turn me on.</a></td></tr>");
            WiServer.print("</table></bdy></html>");
           
            // URL was recognized
            return true;
        }
        // URL not found
        Serial.println("error");
            WiServer.print("<html>");
            WiServer.print("No such page!");
            WiServer.print("</html>");
        return false;
    }


    void setup() {

        // initialize the digital pin as an output:
      pinMode(ledPin, OUTPUT);
      // Initialize WiServer and have it use the sendMyPage function to serve pages
      WiServer.init(sendMyPage);
     
      // Enable Serial output and ask WiServer to generate log messages (optional)
      Serial.begin(57600);
      WiServer.enableVerboseMode(true);
    }

    void loop(){

      // Run WiServer
      WiServer.server_task();

      delay(10);
    }


Eventually, I would like to control a servo through an iphone, but I will not start coding for the servo until I can resolve the connection problem. Does anyone have any idea why the connection would keep dropping?

Thank you,
Davey
DaveyJonze
 
Posts: 2
Joined: Thu Nov 18, 2010 6:41 pm

Previous

Return to Sketches and Applications

Who is online

Users browsing this forum: No registered users and 1 guest

cron