Show Posts
Pages: 1 ... 51 52 [53] 54 55 ... 143
781  Using Arduino / Project Guidance / Re: Need Help With Redirection on: November 27, 2013, 09:15:58 pm
You should rethink any usage of goto you may consider, its best to stick to a controlled program flow over jumping around the place. And you do not really need to worry about exit(), it  is for 'end of program' states such as a failure condition that cannot be resolved.

return is used to end a function and return the execution to the caller ( where the function was originally run ).
it is required for functions that are not declared void. i.e return a value. If a void function always ends on the last line, return is not needed, however it can be used for ending the function earlier, maybe due to a switch or if condition.

break has different meanings, in a switch it is used to stop execution from entering case labels below the active case.
And inside all forms of loops it can be used to jump out of the loop, execution continues after the loop code.

You didn't mention 'continue', inside a loop it causes execution to go the continuation condition without running the rest of the loop code ( skips to next iteration ).
782  Using Arduino / Programming Questions / Re: Wrong values when accessing multidimensional array on: November 26, 2013, 12:01:13 pm
I know, that's why I switched to bytes eventually (plus that I didn't need any values bigger than 7). Before that I used (sizeof(bMap[num])/sizeof(byte) - 1) to get the size of the array.

If you want to use any size (data type) you like and not care about the nitty gritty, here is a fun little example that uses objects to gain a little more info from your arrays.

Code:
#define NUM_NUMBERS 10
#define NUM_PARTS 7

const byte bMap[NUM_NUMBERS][NUM_PARTS] = {  {0, 1, 2, 4, 5, 6}, {2, 5}, {0, 2, 3, 4, 6}, {0, 2, 3, 5, 6}, {1, 2, 3, 5}, {0, 1, 3, 5, 6}, {0, 1, 3, 4, 5, 6}, {0, 2, 5}, {0, 1, 2, 3, 4, 5, 6}, {0, 1, 2, 3, 5, 6} };

template< typename T > struct ArraySize;
template< typename T, size_t N > struct ArraySize< T[N] > { enum{ Size = N }; };
template< typename T, size_t A, size_t N > struct ArraySize< T[A][N] >{ enum{ InnerSize = A, OuterSize = N }; };

void setup() {
  Serial.begin(9600);
  Serial.print( "Size of inner index: " );
  Serial.println( ArraySize< typeof( bMap ) >::InnerSize );
  Serial.print( "Size of outer index: " );
  Serial.println( ArraySize< typeof( bMap ) >::OuterSize );
}

void loop(){}
783  Using Arduino / Programming Questions / Re: Pointer to Print Class (DualWriter) / TelnetServer [solved] on: November 26, 2013, 11:33:16 am
The ampersand (&) character has different meanings depending on where it is. There may not be much logic behind it, it just looks good I suppose. It can specify a reference, be an address-of operator, bitwise and logical 'and' operators ( T &a, &a, a & b, a && b ), the same as * can be used in maths and creating/accessing pointers ( a * b, T *a, *a ).


784  Using Arduino / Programming Questions / Re: Wrong values when accessing multidimensional array on: November 26, 2013, 09:54:13 am
Quote
Here's one thing though: I was using an array of int's before this and I got some weirder results. Because sizeof(bMap[num]) returns 14 when using int's I got double the results in my output. Somewhere in the results it started returning some other values than 0. Thos values weren't in this array, but in a different array (even a different class).

sizeof returns a count of bytes not elements. ints are 2 bytes, resulting in twice the size of the result using char/byte.

785  Using Arduino / Programming Questions / Re: (*XXX).print(); // XXX = pointer to instance that can print on: November 26, 2013, 09:18:06 am
Hi, thanks for the praise, I like helping out.

I realize now why the original code didn't work, also, the original code is the one you want to use, if you weren't doing so.
I'll explain why.

Firstly you are best to initialize the ethernet client like this:
Code:
EthernetClient ethTelnet_Client;

The reason that assigning 0 didn't work, i.e:
Code:
EthernetClient ethTelnet_Client = 0;

Is because this set the internal socket to 0, which is a valid socket number.
The default constructor sets the socket to MAX_SOCK_NUM, and this value is used in the class to decide weather to react to calls that use a real socket.

This is why using an ' anonymous temporary' object worked, i.e:
Code:
EthernetClient ethTelnet_Client = EthernetClient();

This works due to the default constructor in the anonymous temporary setting MAX_SOCK_NUM, then simply passing it on to your object.

So you can safely use the version below as well, but is implicitly done if left to do so.
Code:
EthernetClient ethTelnet_Client = MAX_SOCK_NUM;

So it was this reason my original version seemed to fail, where It was actually incorrect initialization.  smiley-razz
786  Using Arduino / Programming Questions / Re: (*XXX).print(); // XXX = pointer to instance that can print on: November 25, 2013, 08:09:14 pm
Just saw your included code, gotta go to work, but I will have a look through the source later on.
787  Using Arduino / Programming Questions / Re: (*XXX).print(); // XXX = pointer to instance that can print on: November 25, 2013, 07:26:52 pm
Yeah, that class was laid out as a one-time initialiser, here it is modified to take a pointer reference.

I must ask, why are you using a pointer to an EthernetClient, it should be an object, then the original code would work as the EthernetClient won't send when it is not connected. client.stop() resets and it will no longer send if you call print.

Are you using dynamic memory?
Or is it because the DualWriter is global and the EthernetClient is local?
These would explain why the pointer is not available.


This assumes that the pointer variable passed in always exists ( is global or static, just its contents changes ).
This also assumes bad pointers are reset to 0 when done.
Code:
#include <Ethernet.h>
#include <SPI.h>
  class DualWriter : public Print{
 
    public:
   
      DualWriter( Print *p_Out1, Print *p_Out2 ) : OutputA( p_Out1 ), OutputB( p_Out2 ){}

      size_t write( uint8_t u_Data )
        {
          if( OutputA ) OutputA->write( u_Data );
          if( OutputB ) OutputB->write( u_Data );
          return 0x01;
        }
       
    protected:
   
      Print *&OutputA;
      Print *&OutputB;
  }; 

void setup() {
  Serial.begin(9600);
 
  EthernetClient *c = 0x00;
 
//Skips EthernetClient as pointer is 0
  DualWriter d( &Serial, c );
  d.println( F( "PROGMEM!" ) );
  d.println( 1234, HEX );
  d.println( 1.23f );

  //Point c somewhere valid.
  EthernetClient e;

  c = &e;
 
  //Now prints to Serial and EthernetClient
  d.println( F( "PROGMEM!" ) );
  d.println( 1234, HEX );
  d.println( 1.23f );
}

void loop() {}

There is another change you can make if the pointer has a short life ( DualWriter exists longer than the pointer variable, i.e local variable destroyed on function return. ).

Code:
class DualWriter : public Print{

  public:
 
    DualWriter( Print *p_Out1, Print *p_Out2 ) : OutputA( p_Out1 ), OutputB( p_Out2 ){}
 
    void Set( Print *p_Out1, Print *p_Out2 )
      {
        OutputA = p_Out1;
        OutputB = p_Out1;
      }
     
    size_t write( uint8_t u_Data )
      {
        if( OutputA ) OutputA->write( u_Data );
        if( OutputB ) OutputB->write( u_Data );
        return 0x01;
      }
     
  protected:
 
    Print *OutputA;
    Print *OutputB;
}; 

This includes a set function to change the internal ( non-referenced ) pointers.

Code:
void setup() {
  Serial.begin(9600);
 
  EthernetClient c;
 
  //Print twice to serial.
  DualWriter d( &Serial, &Serial );
  d.println( F( "PROGMEM!" ) );
  d.println( 1234, HEX );
  d.println( 1.23f );
 
  //Switch to use ethernet client.
  DualWriter d( &Serial, &c );
  d.println( F( "PROGMEM!" ) );
  d.println( 1234, HEX );
  d.println( 1.23f ); 
}
788  Development / Other Software Development / Re: Base64 stream encoder for Print on: November 25, 2013, 06:40:27 pm
Hi, thanks for the response, I'm not sure I follow, Base64 is a binary to text encoder. You can use the 'x.write()' functions to encode binary data.

If you are after multiple encoding algorithms, then I could try support others like 'yEnc', however a data length is needed for some.
Cheers.
789  Development / Other Software Development / Base64 stream encoder for Print on: November 25, 2013, 10:15:03 am
This is a small test library I made after creating a simple 'dual' printer for a fellow coder here: http://forum.arduino.cc/index.php?topic=200975.msg1481633#msg1481633

I was curious to see what else I could do with the Print library, I have already done an sprintf function. I thought maybe an encryption tool. But Base64 was quick and easy to get rolling, and can be pumped straight down the EthernetClient.

There is no limit to the length of data being encoded. And if there is some interest, a decoder can easily be whipped up.

This library is simple, create an instance and pass a reference to the Print object to receive encoded string.
Code:
Base64Writer b64( Serial );

Use the library like any Print derived class:
Code:
b64.println( F( "PROGMEM String to Base64!" )  );

And finally, if the Base64Writer object doesn't go out of scope before your next direct use of the Print target, call flush() when finsihed:

Code:
Base64Writer b64( Serial );
Serial.println( F( "PROGMEM String to Base64!" )  );
b64.print( F( "PROGMEM String to Base64!" )  );
b64.flush();
Serial.println( F( "\r\nComplete!" )  );

And it produces:
Quote
PROGMEM String to Base64!
UFJPR01FTSBTdHJpbmcgdG8gQmFzZTY0IQ==
Complete!

Here is the code:

Code: (b64Writer.h)
  #include "Arduino.h"
   
  class Base64Writer : public Print{
    public:
   
      Base64Writer( Print &p_Out ) : Output( p_Out ), Cursor( 0x00 ) {}
      ~Base64Writer( void ) { flush(); }
     
      void flush();
      size_t write( uint8_t u_Data );
       
    protected:
   
      void Step( void );
      void Convert( void );
   
      uint8_t Data[ 0x04 ];
      Print &Output;
      char Cursor;
  };

Code: (b64Writer.cpp)
  #include "b64Writer.h"
 
  char b64[ 64 ] PROGMEM = {
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
    'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 
 
  void Base64Writer::flush()
    {
      if( !Cursor ) return;
      Convert();
      switch( Cursor ){
        case 1:  Data[ 0x02 ] = '=';
        case 2:  Data[ 0x03 ] = '=';
      }
      Step();
    }
   
  size_t Base64Writer::write( uint8_t u_Data )
    {
      if( Cursor == 0x03 ){
        Convert();
        Step();
      }
      Data[ Cursor++ ] = u_Data;
      return 0x01;
    }
   
  void Base64Writer::Step( void )
    {
      Output.write( Data, 0x04 );
      memset( Data, 0x00, 0x04 );
      Cursor = 0x00;
    }

  void Base64Writer::Convert( void )
    {
      union{
        uint8_t Input[ 0x03 ];
        struct{
          unsigned int D : 0x06;
          unsigned int C : 0x06;
          unsigned int B : 0x06;
          unsigned int A : 0x06;
        } Output;
      } B64C = { { Data[ 2 ], Data[ 1 ], Data[ 0 ] } };

      Data[ 0x00 ] = pgm_read_byte( &b64[ B64C.Output.A ] );
      Data[ 0x01 ] = pgm_read_byte( &b64[ B64C.Output.B ] );
      Data[ 0x02 ] = pgm_read_byte( &b64[ B64C.Output.C ] );
      Data[ 0x03 ] = pgm_read_byte( &b64[ B64C.Output.D ] );
    }   

Here is my test sketch that uses a paragraph located on wikipedia with verifyable output, and here is an online decoder: http://www.opinionatedgeek.com/dotnet/tools/base64decode/

Code: (test-for-base64-encoder)
#include "b64Writer.h"

void setup() {
  Serial.begin( 9600 );
  Base64Writer b( Serial );
  b.print( F("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.") );
}

void loop(){}

Let me know what you think, or ideas for other encryption/encodings.
Cheers.
790  Using Arduino / Programming Questions / Re: (*XXX).print(); // XXX = pointer to instance that can print on: November 25, 2013, 08:28:11 am
Just gave it a quick test, it works fine:

Code:
void setup() {
  Serial.begin(9600);
 
  DualWriter d0( Serial, Serial );
  DualWriter d1( d0, Serial );

  d1.println( F( "PROGMEM!" ) );
  d1.println( 1234, HEX );
  d1.println( 1.23f );
}

void loop() {}

Produced this output ( multiple \r\n removed ):
Quote
PPPRRROOOGGGMMMEEEMMM!!!
444DDD222
111...222333
791  Using Arduino / Programming Questions / Re: (*XXX).print(); // XXX = pointer to instance that can print on: November 25, 2013, 07:03:47 am
Extending the print class is easy:

Code:
  class DualWriter : public Print{
    public:
      DualWriter( Print &p_Out1, Print &p_Out2 ) : OutputA( p_Out1 ), OutputB( p_Out2 ){}
       
      size_t write( uint8_t u_Data )
        {
          OutputA.write( u_Data );
          OutputB.write( u_Data );
          return 0x01;
        }
    protected:
      Print &OutputA;
      Print &OutputB;
  }; 

Hopefully this should work (class completely untested):

Code:
EthernetClient c;

DualWriter d( Serial, c );

d.print( "this will write to Serial and EthernetClient"  );
792  Community / Bar Sport / Nice little touch. on: November 24, 2013, 04:02:48 am
Nice subtle touch to the forums! (see attached image).
Of course this posts ruins it though.


EDIT: Haha, maybe not, Bar Sport isn't included in post count.
793  Using Arduino / Networking, Protocols, and Devices / Re: HTTP header lines delineated with \r\n or just \n or \r? on: November 24, 2013, 03:33:37 am
No worries, I didn't actually know the answers, but as I've just started coding my server I wish it to be correct too, so answering these types of questions will benefit me just as much, assuming too much always leads to some kind of bug/error down the track.

Here is the link I forgot to post (location of referenced text above)
http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html

And the main reference index:
http://www.w3.org/Protocols/rfc2616/rfc2616.html  << Worth browsing through on a rainy day.
794  Using Arduino / Project Guidance / Re: controlling arduino over wifi from outside my LAN on: November 24, 2013, 02:47:30 am
You should look up the manual for your router and add 'port forwarding' for your arduino's IP & port.
This will allow an internal port accessible from an external address ( internet ).

Or you could try and use/modify this UPNP ( automatic port forwarding ) code for the wifi:
https://github.com/deverick/Arduino-Upnp-PortMapping

Upnp is especially useful if you do not want a static IP/rely on DHCP/or might not know the custom static IP (user set).
795  Using Arduino / Networking, Protocols, and Devices / Re: HTTP header lines delineated with \r\n or just \n or \r? on: November 24, 2013, 02:20:14 am
No, don't add crlf after the message body.

Quote
4.1 Message Types

HTTP messages consist of requests from client to server and responses from server to client.

       HTTP-message   = Request | Response     ; HTTP/1.1 messages
Request (section 5) and Response (section 6) messages use the generic message format of RFC 822 [9] for transferring entities (the payload of the message). Both types of message consist of a start-line, zero or more header fields (also known as "headers"), an empty line (i.e., a line with nothing preceding the CRLF) indicating the end of the header fields, and possibly a message-body.

        generic-message = start-line
                          *(message-header CRLF)
                          CRLF
                          [ message-body ]
        start-line      = Request-Line | Status-Line
In the interest of robustness, servers SHOULD ignore any empty line(s) received where a Request-Line is expected. In other words, if the server is reading the protocol stream at the beginning of a message and receives a CRLF first, it should ignore the CRLF.

Certain buggy HTTP/1.0 client implementations generate extra CRLF's after a POST request. To restate what is explicitly forbidden by the BNF, an HTTP/1.1 client MUST NOT preface or follow a request with an extra CRLF.
Pages: 1 ... 51 52 [53] 54 55 ... 143