Go Down

Topic: how to save a sketch as *.h and *.cpp? (Read 4652 times) previous topic - next topic

CO2scaboo

Good morning

I am trying to create a library for the first time. My sketch has become to big for the Uno board, so I created some functions to reduce the size, but it is still too big.
So I am making the leap to put my functions in a library. I have read the creating library page in hacking under learning and the library page in play ground. I have a good grasp of how to write the code, but I am missing how to save as the *.h and *.cpp files.

Am I blind or is it not explained on those two pages? Can someone please explain to me if it is not?

Thanks in advance

johnwasser

It is unlikely that moving functions to a library will make them any smaller.

If your program is too big for an UNO you might want to invest in a MEGA.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

mhectorgato

This wasn't very clear to me either.

In the Arduino IDE, underneath the SerialMonitor button, click the down arrow and select "New Tab". Then you can create the separate files.

Or in Windows, you can hit  Ctrl+Shift+N

CO2scaboo

@John-I was thinking that might be a reply. I wasn't sure if creating a library would actually use less program memory or not.
@hector- Thanks for the advice!

PeterH

Moving your code into a library would not usually make it any smaller, but if it is poorly designed then refactoring it could make a big difference. If you posted your code and explained whether you are trying to reduce code and/or RAM and by how much, no doubt you would get feedback about possible ways to achieve that.

mhectorgato


@John-I was thinking that might be a reply. I wasn't sure if creating a library would actually use less program memory or not.
@hector- Thanks for the advice!


In a learning exercise, I encapsulated some functionality regarding SharpIRs into classes, including averaging.

If I had several of these devices connected, it would seem to me (don't know the compile sizes) that there would be a tipping point in size where having a class oriented approach would save on program compile size.

My thought was that I wouldn't have code to declare and manipulate (the latest reading, an array to hold recent readings, total/average values) variables several times over, but instead having a single object reference.

PaulS

Quote
My thought was that I wouldn't have code to declare and manipulate (the latest reading, an array to hold recent readings, total/average values) variables several times over, but instead having a single object reference.

Per device, yes. You wouldn't use the same class instance for all of the sensors. That would defeat the purpose of keeping recent readings, etc.

Each instance is going to replicate the amount of memory needed.
The art of getting good answers lies in asking good questions.

johnwasser


If I had several of these devices connected, it would seem to me (don't know the compile sizes) that there would be a tipping point in size where having a class oriented approach would save on program compile size.

My thought was that I wouldn't have code to declare and manipulate (the latest reading, an array to hold recent readings, total/average values) variables several times over, but instead having a single object reference.


Turning blocks of code into functions will often help with code size if the same block of code appears more than once in your program.  That's turning two or more nearly identical blocks of code into two or more function calls and one block of code.

Turning a bunch of related functions and variables into a 'class' is more for ease of readability than code space.  The functions and data won't take up any less space because they are in a class.

If you care to upload your code to someplace like pastebin.com we can take a look and advise ways to get the code size down.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

PaulS

Quote
If you care to upload your code to someplace like pastebin.com we can take a look and advise ways to get the code size down.

Even better would be to just attach it, using the Additional Options link.
The art of getting good answers lies in asking good questions.

mhectorgato



If I had several of these devices connected, it would seem to me (don't know the compile sizes) that there would be a tipping point in size where having a class oriented approach would save on program compile size.

My thought was that I wouldn't have code to declare and manipulate (the latest reading, an array to hold recent readings, total/average values) variables several times over, but instead having a single object reference.


Turning blocks of code into functions will often help with code size if the same block of code appears more than once in your program.  That's turning two or more nearly identical blocks of code into two or more function calls and one block of code.

Turning a bunch of related functions and variables into a 'class' is more for ease of readability than code space.  The functions and data won't take up any less space because they are in a class.

If you care to upload your code to someplace like pastebin.com we can take a look and advise ways to get the code size down.


As soon as I get in front of my system with the code I will. Again it was more of an exercise than anything else.

When I referred to space, I was thinking of reducing the size of the compiled code, the space used in flash. I understand that each time that class was instanciated it would take up more SRAM space.

Looking at the spec sheet for the Micro, maybe I had my priorities reversed!  Side question -- Is there a simple way to get free SRAM size while a sketch is running?

Quote
Flash Memory = 32 KB (ATmega32u4) of which 4 KB used by bootloader
SRAM    = 2.5 KB (ATmega32u4)


Thnaks

johnwasser

Code: [Select]

// MemoryFree.h
// Library based on code posted here:
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213583720/15
//
// Extended by Matthew Murdoch to include walking of the free list.
//
#ifndef MEMORY_FREE_H
#define MEMORY_FREE_H
#ifdef __cplusplus
extern "C" {
#endif

int freeMemory();

#ifdef  __cplusplus
}
#endif
#endif



Code: [Select]

// MemoryFree.c
// Library based on code posted here:
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213583720/15
//
// Extended by Matthew Murdoch to include walking of the free list.
//
#if (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

extern unsigned int __heap_start;
extern void *__brkval;

/*
* The free list structure as maintained by the
* avr-libc memory allocation routines.
*/
struct __freelist {
  size_t sz;
  struct __freelist *nx;
};

/* The head of the free list structure */
extern struct __freelist *__flp;

#include "MemoryFree.h";

/* Calculates the size of the free list */
int freeListSize() {
  struct __freelist* current;
  int total = 0;

  for (current = __flp; current; current = current->nx) {
    total += 2; /* Add two bytes for the memory block's header  */
    total += (int) current->sz;
  }

  return total;
}

int freeMemory() {
  int free_memory;

  if ((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__heap_start);
  } else {
    free_memory = ((int)&free_memory) - ((int)__brkval);
    free_memory += freeListSize();
  }
  return free_memory;
}
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

mhectorgato


DrRobertPatzke

I try to create modular programs, i.e. I make a library of everything, which I might use for different applications (sketches).
Thus, my different sketches are rather short.
But I use another editor for creating libraries (PSPAD from Jan Fiala) and I have a testing sketch in each library folder.

This approach has implicitly .H and .C/.CPP files for the libraries.
Of course, this is not a way to save code, in most cases it even needs more code for creating extra utility functions in the libraries.
But I am learning with Arduino Due and till now, I am not afraid to touch the limit of code space.

mhectorgato

Here's the code

SensorProject.ino
Code: [Select]

#include <SoftwareSerial.h>
#include "SharpSensor.h"
#include "SerialLCD.h"

SerialLCD screen = SerialLCD(1);

int pin1 = A0;
int pin2 = A1;

int pinX = A3;
int pinY = A4;
int pinZ = A5;

SharpSensor sensor1(pin1, 5);
SharpSensor sensor2(pin2, 5);

bool ledON = false;

unsigned long lastMillis = 0;

void setup() {
  Serial.begin(9600);

  // put your setup code here, to run once:
  ledON = true;
  digitalWrite(13,HIGH);

  pinMode(1, OUTPUT);
  digitalWrite(1, HIGH);

  screen.init();
}

void loop() {

  sensor1.getReading(); 
  sensor2.getReading();

//  triAxis.readSensor();

  if ((millis() - lastMillis) > 500)
  { 
    if (ledON)
    {
      ledON = false;
      digitalWrite(13,LOW);
    }
    else
    {     
      ledON = true;
      digitalWrite(13,HIGH);
    }

    String str = "One : " + String(sensor1.getAverage());
    String str2 =  "Two: " + String(sensor2.getAverage());
    screen.writeString(str, str2);
    lastMillis = millis();
  } 
  delay(50);
}


SharpSensor.h
Code: [Select]

#include "Arduino.h"
class SharpSensor
{
public:
  SharpSensor(int pin, int readings);
  void getReading();
  int getAverage();

private:
  int _pin;
  int _arraySize;
  int _arrayOfReadings[10]; 
};


SharpSensor.cpp
Code: [Select]

#include "SharpSensor.h"
SharpSensor::SharpSensor(int pin, int readings)
{
  _pin = pin;
  pinMode(_pin, INPUT);

  _arraySize = readings;
  // TODO: Change to malloc / realloc to use dynamic array
}

void SharpSensor::getReading()
{
  for (int i= _arraySize - 1; i > 0; i--)
  {
    _arrayOfReadings[i] = _arrayOfReadings[i - 1];
  }
  _arrayOfReadings[0] = analogRead(_pin);
}

int SharpSensor::getAverage()

  int total = 0;
  for (int i=0; i < _arraySize; i++)
  {
    total += _arrayOfReadings[i];
  }
  return total / _arraySize;
}


SerialDIsplay.h
Code: [Select]

#include <SoftwareSerial.h>
#include "Arduino.h"

class SerialLCD
{
public:
  SerialLCD(int pin);
  void init();
  void clearScreen();
  void lineWrap();
  void writeString(String data);
  void writeLineString(String data);
  void writeString(String data1, String data2);
 
private:
  SoftwareSerial _mySerial;
  int _pin;
};


SerialLCD.cpp
Code: [Select]

#include "SerialLCD.h"

SerialLCD::SerialLCD(int pin) :
_mySerial(255, 1)
{
  _pin = pin;
}

void SerialLCD::init()
{
  pinMode(_pin, OUTPUT);
  digitalWrite(_pin, HIGH);
  _mySerial.begin(9600);
  delay(100);

  _mySerial.write(12);                 // Clear             
  _mySerial.write(17);                 // Turn backlight on
  delay(5);                           // Required delay
  _mySerial.print("Hello, world...");  // First line
  _mySerial.write(13);                 // Form feed
  delay(5);                           // Required delay
  _mySerial.print("from Parallax!");   // Second line
}

void SerialLCD::clearScreen()
{
  _mySerial.write(12);
  delay(5);
}
void SerialLCD::lineWrap()
{
  _mySerial.write(13);
  delay(5);
}
void SerialLCD::writeString(String data)
{
  _mySerial.print(data);
}
void SerialLCD::writeString(String data1, String data2)
{
  _mySerial.write(12);
  _mySerial.print(data1);
  _mySerial.write(13);
  delay(5);
  _mySerial.print(data2);
  delay(5);
}
void SerialLCD::writeLineString(String data)
{
  writeString(data);
  lineWrap(); 
}



Go Up