Pages: [1]   Go Down
Author Topic: Strange class problem  (Read 944 times)
0 Members and 1 Guest are viewing this topic.
Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

I have a strange problem with my selfmade class. I want to use some DMX spots over WiFi, so I created a simple sketch for a client (Arduino+WiFi) and a sketch for a server  (Arduino+Ethernet). For the server I wrote a class called DMX_RGB (see attached). I need to create some instances (globaly)in DMXNet_Server.ino:

Code:
DMX_RGB Bar1("192.168.1.40",4711,10,11,12,9,8);

When I create such an instance, the sketch stops and nothing happens anymore. Also no debug output on the serial monitor...

If I comment out everything which is relating to the instance Bar1 (and of course the code above) the sketch works (also it is not doing what I want :-( )

I think it is a simple, stupid problem - but I cannot find where. Has anyone an idea?

Thanks a lot, Holger

* DMX_RGB.h (1.28 KB - downloaded 9 times.)
* DMX_RGB.cpp (3.33 KB - downloaded 7 times.)
* DMXNet_Server.ino (1.79 KB - downloaded 5 times.)
Logged

Perl is the only language that looks the same before and after RSA encryption.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Has anyone an idea?
I'm going to guess that you are running out of memory.
Logged

USA
Offline Offline
Full Member
***
Karma: 0
Posts: 235
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know what the function dbg does but I imagine it "prints" out characters over the serial link.  My guess is that the UART isn't initialized yet.  Try commenting out the dbg function calls in the constructor of DMX_RGB.
Logged

0
Offline Offline
Shannon Member
****
Karma: 161
Posts: 10431
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If its not a Mega you should check the amount of RAM in use - for instance what value is UDP_TX_PACKET_MAX_SIZE ?
Logged

[ I won't respond to messages, use the forum please ]

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I agree with mkwired. You have probably fallen prey to the "static initialization order fiasco" (Google it).

I suggest you do a minimal number of things in your constructor (for example, save the arguments into class variables). Then make a DMX_RGB::begin() method and do the rest there.
Logged

Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all!

thanks for your hints. I wonder that one class instance would need so much memory. I will try your suggestions and write the solution to this thread as soon as possible.

Regards, Holger
« Last Edit: November 07, 2012, 03:23:58 am by Codeman » Logged

Perl is the only language that looks the same before and after RSA encryption.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I wonder that one class instance would need so much memory.
There's this:
Code:
  byte _red;
  byte _green;
  byte _blue;
  byte _dim;
  byte _red_memory;
  byte _green_memory;
  byte _blue_memory;
  byte _dim_memory;
  float _steps;
  int _addr_red;
  int _addr_green;
  int _addr_blue;
  int _addr_dim;
  int _addr_mode;
  float _stepping_red;
  float _stepping_green;
  float _stepping_blue;
  byte _queue_red[MAX_FADE_ELEMENTS];
  byte _queue_green[MAX_FADE_ELEMENTS];
  byte _queue_blue[MAX_FADE_ELEMENTS];
  float _queue_time[MAX_FADE_ELEMENTS];
  int _queue_counter;
  int _q;
  int _step_counter;
  IPAddress remote_ip;
  uint16_t remote_port;

and this:
Code:
  void _DMXNet_send(uint16_t addr,uint8_t data);
  DMX_RGB(char* ip, uint16_t port,int addr_red, int addr_green, int addr_blue, int addr_dim,int addr_mode);
  void set_rgb(byte r, byte g, byte b);
  void set_red(byte r);
  void set_green(byte g);
  void set_blue(byte b);
  void set_dim(byte d);
  int get_steps(void);
  void fade_to(byte r, byte g, byte b, float time);
  void flash(byte flashes, int min_time, int max_time, int fade_time);
  void worker(void);
  void init(int cmd);

That's not a trivial list of data fields or a trivial list of functions. For EACH instance.
Logged

0
Offline Offline
Shannon Member
****
Karma: 161
Posts: 10431
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Methods are shared between all instances.

And 50 bytes or so isn't "massive".
Logged

[ I won't respond to messages, use the forum please ]

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Methods are shared between all instances.

And 50 bytes or so isn't "massive".
50?  How big is MAX_FADE_ELEMENTS?
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

ok, I see, that my Uno is not a memory giant... and my class is not very small. But with MAX_FADE_ELEMENTS set to 10 the storage for one instance should be about 180 Bytes. I tried to use only _one_ instance and the Arduino freezes.

Nick Gammon's hint was the solution (not for everything, but now it works!): The constructor was "too big" - don't ask me why this is a problem. But when rewriting the constructor function to a DMX_RGB.begin() method it works! Also four instances are working! I took a look at http://www.arduino.cc/playground/Code/AvailableMemory and checked my free memory and there were about 300 bytes empty.

If anyone can explain why the constructor was the problem and why I should use a begin()-method for initialization I would be very glad!

Thanks for helping!

Holger
 smiley-cool
Logged

Perl is the only language that looks the same before and after RSA encryption.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The constructor was "too big" - don't ask me why this is a problem.
It wasn't "too big". It was that the stuff that it did, it did when the rest of the processor was not ready for it to do things. Using the Serial instance, as an example, before the Serial instance has been created.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

PaulS is right. You really need to read up on "static initialization order fiasco".

The order in which static data is instantiated is undefined, particularly between compilation units. In your case, if you are using Serial, then Serial.begin() is done in setup, but if your dbg class uses Serial it will definitely be calling it too soon (the constructor will be called before setup).

The same remark applies to timers, and indeed anything related to Arduino libraries.
Logged

Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, I understand what my problem was.

Thanks for your help!

Holger
Logged

Perl is the only language that looks the same before and after RSA encryption.

Pages: [1]   Go Up
Jump to: