Setup function not running due to initialized class?

Hello,
I’m new to this forum but I have been tinkering with the Arduino for a while.
I have built a library that deals with Ethernet and UDP, and when I try to initialize the class the setup function won’t run. Here’s a small test I ran to figure out whats going wrong:

#include <Mylib.h> //Library I created
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //mac address for Ethernet shield 
IPAddress ip(192, 168, 0, 20); //Ip Address set from network
  Mylib lib;
  EthernetUDP Udp;
void setup()
{
    Ethernet.begin(mac,ip); //begins Ethernet connection 
    Udp.begin(6454); 
  Serial.begin(9600);
  Serial.println("started");
}
void loop()
{
 Serial.println("test"); 
}

Which doesn’t display anything in serial. Which doesn’t make sense.

however when I comment out Mylib lib; everything works.

is it part of the library that is messing with everything?
Any help you can give me on the subject will be greatly appreciated.
Thanks!

The initialization of the class is done before setup().

Perhaps your class has an endless loop ?

Thanks for a quick reply.
The class functions are only made up of for and if statements, there aren't any loops in the class.

Interesting bug.

You'll get much better advice if you post the class code here, too.

-br

Here is the class code.

#include "Arduino.h"
#include "Artnet2.h"
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>


Artnet2::Artnet2()
{
	Udp.begin(6454); 
	pinMode(3,OUTPUT);
	
	bool matchArtnet = true; 
	char _artnetHeader[] = "Art-Net";
	int _channel_position = 1;
	int _number_of_channels = 512;

	
}
bool Artnet2::read() //reads UDP packet to Artnet Buffer
{
  Udp.parsePacket();
  Udp.read(_AnetBuffer,1024);
	for (int i=0; i<7; i++) {
		if (_AnetBuffer[i]!=_artnetHeader[i])
		{
			matchArtnet = false;
			break;
		}
	}
	return (matchArtnet);
}
int Artnet2::interpret() //Decides if its a DMX information or Artnet poll
{
  _Opcode=byte(_AnetBuffer[9]);
     
     if(_Opcode==0x5000)
      {
		  _opcode_is = 1;
      }   
       
     else if(_Opcode==0x2000)
     {
		 _opcode_is = 2;
     } 
	return (_opcode_is);
}
void Artnet2::send() //sends Artpoll reply
{
  //send reply somehow update in next version
}
void Artnet2::dMX() //Outputs DMX signal read from Artnet Buffer on pin3 
{
   for(int i=_channel_position-1;i< _number_of_channels;i++)//channel position
      {
       analogWrite(3,_AnetBuffer[i+17]);
      }
}

If memory serves me right it does not work to call functions like UDP.begin() or pinMode() from your constructor because the hardware is not completely initialized when the constructor is called. Search the forums, this is a well-worked topic.

Perhaps if you add a .begin() method and do the work there...

-br

The class functions are only made up of for and if statements, there aren’t any loops in the class.

For are loops!

Your also doing

	Udp.begin(6454);

this twice once in Artnet2 and once in setup().

This won’t work

bool Artnet2::read() //reads UDP packet to Artnet Buffer
{
  Udp.parsePacket();
  Udp.read(_AnetBuffer,1024);
	for (int i=0; i<7; i++) {
		if (_AnetBuffer[i]!=_artnetHeader[i])
		{
			matchArtnet = false;
			break;
		}
	}
	return (matchArtnet);
}

as you need to set matchArtnet = true before the for loop not just once when the class is created.

I don’t know what Arduino you have but 1024 chars is half the ram of the UNO!

I don’t see this working (may be wrong)

       analogWrite(3,_AnetBuffer[i+17]);

Mark

Thank you all for your quick replies!

Ok, I’ve created a new method in the class “.start” to solve the multiple Udp initializations, and Ive commented out the two “for” loops in the class, and it still isn’t displaying anything in serial.

Class code as an update:

#include "Arduino.h"
#include "Artnet2.h"
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>


Artnet2::Artnet2()
{
	bool matchArtnet = true; // Artnet global varification
	char _artnetHeader[] = "Art-Net";// for Artnet varification 
	int _channel_position = 1;
	int _number_of_channels = 512;
}
//find a way to integrate artnet.start in next version
void Artnet2::start()
{
	pinMode(3,OUTPUT);
	Udp.begin(6454);
}
bool Artnet2::read() //reads UDP packet to Artnet Buffer
{
  Udp.parsePacket();
  Udp.read(_AnetBuffer,1024);
	/*for (int i=0; i<7; i++) {
		if (_AnetBuffer[i]!=_artnetHeader[i])
		{
			matchArtnet = false;
			break;
		}
	}
	return (matchArtnet);*/
}
int Artnet2::interpret() //Decides if its a DMX information or Artnet poll
{
  _Opcode=byte(_AnetBuffer[9]);
     
     if(_Opcode==0x5000)
      {
		  _opcode_is = 1;
      }   
       
     else if(_Opcode==0x2000)
     {
		 _opcode_is = 2;
     } 
	return (_opcode_is);
}
void Artnet2::send() //sends Artpoll reply
{
  //send reply somehow update in next version
}
void Artnet2::dMX() //Outputs DMX signal read from Artnet Buffer on pin3 
{
   /*for(int i=_channel_position-1;i< _number_of_channels;i++)//channel position
      {
       analogWrite(3,_AnetBuffer[i+17]);
      }*/
}

Arduino Sketch:

#include <Artnet2.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

  byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //mac address for Ethernet shield 
  IPAddress ip(192, 168, 0, 20); //Ip Address set from network

  Artnet2 aNet;
void setup()
{
  
    Ethernet.begin(mac,ip); //begins Ethernet connection 
    aNet.start();  
    
  Serial.begin(9600);
  Serial.println("started");
  
}

void loop()
{

      Serial.print("Art-Net try?");
      aNet.read();
    

  if(aNet.interpret()==1) //Detirmine if Art-Net packet is ArtDMX or Artpoll 
    {
      Serial.print("Art-Net Achieved!");
      aNet.dMX(); //output to DMX network
    }
  
  else if (aNet.interpret()==2)
    {
      Serial.print("Art-Net Achieved!");
       aNet.send(); //send Artpoll reply 
    }
}

The var's in this function only exist within this function

Artnet2::Artnet2()
{
	bool matchArtnet = true; // Artnet global varification
	char _artnetHeader[] = "Art-Net";// for Artnet varification 
	int _channel_position = 1;
	int _number_of_channels = 512;
}

Post your .h file.

Mark

Read/re-read this http://arduino.cc/en/Hacking/LibraryTutorial

Mark

Here’s the Header:

#ifndef Artnet2_h
#include "Arduino.h"
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>


class Artnet2
{
 public:
	Artnet2();
	void start(); //integrate in next version
	bool read();
	int interpret();
	void send();
	void dMX();
	
	EthernetUDP Udp;
	bool matchArtnet;
	
 private:
	char _AnetBuffer[1024];
	byte _dmxBuffer[513];
	char _artnetHeader[7];
	short _Opcode;
	int _channel_position;
	int _number_of_channels;
	int _opcode_is;
};
#endif

I’ve read/reread/rereread… etc. the tutorial but I can’t seem to figure out whats going on. I followed the steps as I was making my own library

You didn't answer holmes4's question - which Arduino do you have - you're being awfully cavalier with buffer sizes if you have an uno.

 private:
	char _AnetBuffer[1024];
	byte _dmxBuffer[513];

3/4 of the memory of a 328 based Arduino is abused by one instance of your class.

Artnet2::Artnet2()
{
	bool matchArtnet = true; // Artnet global varification
	char _artnetHeader[] = "Art-Net";// for Artnet varification 
	int _channel_position = 1;
	int _number_of_channels = 512;
}

You have a scope problem in the above.

Mark

I have an uno, however I am only making one instance of this class when this program is run and the buffers need to be that large to hold the information being sent. I wanted to build a library to see if I could.
Do you guys suggest something else?

The Uno has 2k of RAM, http://arduino.cc/en/Main/arduinoBoardUno

I agree with Professor Holmes. That code in reply 13 is nonsense.

I guess I dont understand what is nonsense about it?
Im sorry I just tinker, I am not a programmer by any means.

I understand this is only an initial version of the library, but at the moment it seems it only does the following:

  • check for a header (whose content, I assume, is outside your control, but is 7 byte long);
  • check whether is a poll request, in which case send a reply;
  • or, alternatively, relay the packet through an analog port (presumably a DMX chain).

I see nothing in your code indicating a change of state in the Arduino, or the need to keep track of the configuration. If so (I'm exaggerating), you wouldn't need big-sized variables. How much RAM you'll really need will be determined by how complex are the states you'll need to manage, if any.

The main issue is buffering, because you'll be receiving data from Ethernet and sending it through an analog port. You'll need to rework your code, but after reading the first bytes (the header and the 'command'), you may enter a cycle of reading short chunks of data from Udp and writing them to analog, recycling the buffer (let's say a 256 byte array). You need to figure out whether the speed and timeout values allow you to make this reliably using a small buffer size. Maybe you could give us some background on these features.

Art-Net is a ethernet protocol for entertainment lighting. It carries in it a DMX chain, I would like to convert the Art-Net protocol to a DMX protocol. from what I can tell the DMX signal isn't encoded any farther in Art-Net then past all of the header stuff.

basically I would like to have a library that:
verifies packet received is Art-Net. (the first part of the Art-Net protocol sends "Art-Net")
interprets it between an Artpoll or DMX information
and sends via analog pin to DMX