I am doing a little project which involve an intelligent TFT display from Electronic Assembly and I have written a whole bunch of convenience functions to control this display, like clear screen, draw line, draw rectangle, etc.
At the moment, this is just another .ino-file in my sketch, but I would like to make it a "real library" and publish it under the GPL.
However, I'm no developer, meaning, I don't have any formal coding training or huge experience. I have no idea how to make a library from a .ino-file.
Could somebody gice some advice how to make a library or point me to some tutorial?
I posted the code above. There is the function sendData() which actually transmits the commands to the TFT and is called by any other function in the library.
Basically, all functions just put together a command string and then call sendData.
Edit:
sendData() is a public function because it should also be possible to call it from external in case there is a command which I didn't implement in the lib yet.
The space key is not important to the compiler, usually, but it does make for more readable code.
There are some other things you could do. command does not need to be an array to hold one value. You could use:
char cmd = 12;
sendData(&cmd, 1);
But, if you wish to keep it an array, for consistency with other functions where the array contains more than one element, you should use the sizeof() macro, and let the compiler do the counting:
sendData(command, sizeof(command));
That way, if you copy/paste the function and change the size of the array, you don't need to count the number of elements in the new array.
I was avoiding sizeOf() yet because I'm not sure how it reacts to null elements, i.e. if it sees null elements as terminators and thus may deliver wrong results.
Which functions do you think should be private? The only function I could think of would be sendData() but I kept it yet public intentionally because I haven't implemented functions for all commands yet. So, this way, the user can still use sendData() to send commands "by hand". This will become especially important when I succeeded implementing EA's proprietary smallprotocol which includes some checksum calculations and such.
Now I ran into a problem which doesn't mean anything to me...
I want to pass the serial port to use for comms to the library in a parameter. In sendData(), I then check this parameter and decide, which Serial to use:
EDIPTFT::EDIPTFT(int port, int smallprotocol) {
_port = port;
_smallprotocol = smallprotocol;
}
void EDIPTFT::sendData(char* data, int len) {
if (_smallprotocol > 0) {
}
else {
unsigned char i;
for(i=0; i < len; i++) {
switch (_port) {
case 0 : {
Serial.write(data[i]);
break;
}
case 1 : {
Serial1.write(data[i]);
break;
}
case 2 : {
Serial2.write(data[i]);
break;
}
case 3 : {
Serial3.write(data[i]);
break;
}
}
}
}
}
I use this library from a sketch that also uses the FastSerial library. Now, when I try to compile everything, I get this errors:
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `__vector_25'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
/opt/arduino-1.0.3/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../avr/bin/ld: Disabling relaxation: it will not work with multiple definitions
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `__vector_36'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `__vector_51'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `__vector_54'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `Serial'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
/opt/arduino-1.0.3/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../avr/bin/ld: Warning: size of symbol `Serial' changed from 29 in UxV_CS.cpp.o to 34 in core.a(HardwareSerial.cpp.o)
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `Serial1'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
/opt/arduino-1.0.3/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../avr/bin/ld: Warning: size of symbol `Serial1' changed from 29 in UxV_CS.cpp.o to 34 in core.a(HardwareSerial.cpp.o)
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `Serial2'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
/opt/arduino-1.0.3/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../avr/bin/ld: Warning: size of symbol `Serial2' changed from 29 in UxV_CS.cpp.o to 34 in core.a(HardwareSerial.cpp.o)
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `Serial3'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
/opt/arduino-1.0.3/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../avr/bin/ld: Warning: size of symbol `Serial3' changed from 29 in UxV_CS.cpp.o to 34 in core.a(HardwareSerial.cpp.o)
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `__vector_26'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `__vector_37'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `__vector_52'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
core.a(HardwareSerial.cpp.o): In function `global constructors keyed to rx_buffer':
/opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of `__vector_55'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
The keywords public, protected and private are meant for capsulating or hiding the members. Public is the interface part that is accessible from outside. I tend to define other functions that are not necessarily safe to call from outside in the protected part. These are the kind of functions that are called by the implementation.
I guess it's just a habit that I also leave the private part for member variables, not function, that then have accessor functions in the public part if necessary. In some rare cases, I do also write private functions, but I have meant to only use them for filling some member arrays and only meant to be called by the other functions in the same class. These wouldn't necessarily be safe to call even from inherited classes, strictly internal logic.
Anyways, if you think you need access to a function, just raise it to public level. Separating the functions to public and protected sections also gives other coders hints towards the usage of the design. Coders would just look at the public functions with comments in the header file and should be able to tell how to use it from that. Too bad Arduino IDE does not give any popup hints when you try and access the functions within a class instance, so you need to actually open the header file to see what's in there or rely on documentation anyways.
SierraWhiskey:
Now I ran into a problem which doesn't mean anything to me...
core.a(HardwareSerial.cpp.o): In function global constructors keyed to rx_buffer': /opt/arduino-1.0.3/hardware/arduino/cores/arduino/HardwareSerial.cpp:515: multiple definition of __vector_55'
UxV_CS.cpp.o:/opt/arduino-1.0.3/UxV_CS.ino:79: first defined here
This is way out of my league... What do I do now?
Maybe the same header file is getting included twice. I'm not familiar with FastSerial or Arduino in general, yet, but in all other kinds of projects we avoid including the headers twice by adding some macro definition in the beginning of the said header file.
For example, picked this for LiquidCrystal library:
So, at the start of your library header file, it should say something like that, but using some other unique string in place of LiquidCrystal_I2C_h. Same goes for other header files, and they should also have their own unique id strings. And the header file should end with #endif on a new line. This avoid duplicate inclusion.
Not seeing the rest of your code, I'm assuming something like this has happened here.
Oh, ok, that looks ok to me, and I can compile it just fine too with my own bare bones sketch, that includes HardwareSerial. I had to comment out Serial1-3 in this system. It did compile for Mega with those lines uncommented. The error does sound like some kind of dependency mix up though.
May I jump in here with a related question? I have been playing with a TM1638 LED display (8 characters 7 segments using I2C) and encountered the sendData function. I have searched the header files from the library, the .cpp files, even did a search of my whole Arduino directory for ". containing sendData". I have been unable to find the body of the function, where the actual code resides. The prototype is in the header files, the class is instantiated in the .cpp files but nowhere could I find the function. The code compiles and uploads and runs with no problems; I just can't find what exactly it is doing. Since you seem to be dealing with the same function I hope you could point me to where I could study the function so I could understand what it is doing in more than a general sense like "is sends the data that has been readied."
Any help would be appreciated.
Thanks