Help converting a simple code from procedural to object oriented

I read a number of books on C++ before it finally clicked for me. The one that did it was unsurprisingly, an O'Reilly publication: "C++, the core language". It's short and doesn't cover everything and it's now several revisions of C++ out of date.

I still recommend it though, because it has everything you need to understand about classes and how they work. The specifics and fancier new stuff you can pick up when you need to. The word Arduino does not appear in the book though :wink:

Protected and private is a bit subtle. Protected members are accessible to classes that inherit from the class. Private members aren't. I've never needed a protected member.

1 Like

Every class member function can access private variables.

1 Like

tl;dr: Learn C.

and you also say

which between the two inform the answer and the advice I always give, which is my opinion and as you may see, not everyone's, viz:

Get a solid knowledge of C. By modern standards it is a tiny language, it has been around for some time and is, with some minor differences, at the core of many modern languages.

Nothing you learn by mastering C will be wasted when you open up your horizons, as in a desire to go "from procedural to object oriented".

Also, when it comes to these tiny computers we use, with limited resources, it is often not necessary or appropriate to use C++. And libraries written with the "full power" of C++ can be used w/o knowing anything about what's going on inside. Here basic examples and a modicum of pattern matching can suffice.

Years ago people thought it was crazy to use C on micros. Assembly language snobs enthusiasts may have had a point, but modern compilers are quite amazing and C is, again my opinion, more appropriate often, the exception being (maybe) at the lowest levels of coding.

And today C++ proponents may be as wrong to insist on using C++. Again, in the context of tiny programs running on resource-limited hardware.

One step further is my recommendation that the mastery of C need not involve microprocessors at all; again, nothing you learn will ever have been wasted time, even if you write and perfect programs that just run on the PC. I use several online compilers, even for Arduino development, where I often can get most of the logic working independent of how I have wired some buttons or LEDs.

I can read some C++, and I have modified C++ programs. I have made a few objects or classes or whatever they called in an experimental way, but most of what I use to make these little toys do what I want is straight ahead C that would have been valid, for the most part, 50 years ago or so.

As always, YMMV. Good luck whatever path you take, μπορεί ο άνεμος να είναι πίσω από τα πανιά σου.

a7

1 Like

Even without using accessors yes ?

I really dont know what to say. Every time i am about to give up, you all give me courage to keep trying and eventually to learn something more.

I submit my respec to each one personally and to all of you together !
THANK YOU !

https://codescracker.com/cpp/cpp-inheritance.htm

1 Like

I totally agree with this.

-jim lee

Sir, if it is possible for you and not too much trouble, could you please explain to me how the highlighted (bold) parts of the code work ? To be more specific, how exactly each method know which port to listen to ?
Thank you in advance.
P.S.
For some reason only the stars are visible, not the actual bolded text...

When each "GPSPort" object is created it is given that address (&) of the Stream object it should use. HardwareSerial objects (Serial, Serial1, Serial2, Serial3) are a kind of Stream object because class HardwareSerial is derived from the base class Stream.

I thought I had explained that when I said:

You did. It's just me that cant comprehend it. I need to study and practice pointers throughly. not to mention that i have no idea about how exactly heritage works.
Thank you nontheless.

Get some books. I came from a C background and it took four of them for me to finally get C++. Worse, I found that the understanding I had wasn't necessarily sufficient to actually use the language - OO designs can be tricky to get right, especially to start with.

Then write code. Lots of it. If there's a magic bullet, that's it

You are right. I guess there is no other way since i can neither afford private lessons nor can i get back to school.

Good afternoon everyone.
I am not quite sure if i should post this here or not since it is not the kind of question that concerns the title of the topic but it is kind of relevant to the above mentioned codes.
Today as i was thinking about the above code, i had an idea. Last month i was experimenting with an ethernet enc28j60 module. So i say to myself: Since i have the data on my USB port, why not be able to also send them via Ethernet UDP to a network ?
The last few days i have been experimenting in turning the above code into a library. I actually managed to create my own library out of the suggested code. So how can i now use the EthernetENC.h library (inside my own library) to make it send the data to both usb and network ?
Is there an easy enough way to do this ?
The purpose of my question is to get a clue how to use a library inside my own library. do i make sense ?

I have actually altered the code provided by sir johnwasser in post #10 to suit my coding style (the one im used to when it comes to handling serial data).
So here is the .h file :

#ifndef Builder_H
#define Builder_H
#include <Arduino.h>

class Builder
{
  public:
    Builder(Stream *serialport) : serialport(serialport) {}
    void update(char SM, char EM);
  private:
    Stream * serialport;
    char buffer[100];
    byte nde = 0;  //index
    bool rcving = false;
    char _SM;
    char _EM;
};

#endif

Here is the .cpp file :

#include "Builder.h"

void Builder::update(char SM, char EM)
{
  _SM = SM;
  _EM = EM;
  if (serialport->available())
  {
    char  rc = serialport->read();
    if (rcving)
    {
      if (rc !=_EM)
      {
        buffer[nde] = rc;
        nde++;
        if (nde >= 99)  
        {
          nde = nde - 1;
        }
        buffer[nde] = '\0';
      }
      else
      {
        buffer[nde] = '\n';
        nde++;
        buffer[nde] = '\0';
        rcving = false;
        nde = 0;
        Serial.print(buffer);
      }
    }
    else if (rc == _SM)
    {
      rcving = true;            
    }
  }
}

and last here is the .ino file :

#include "Builder.h"

Builder GPS1(&Serial1);
Builder GPS2(&Serial2);

void setup()
{
  Serial.begin(38400);  // USB port
  Serial1.begin(9600);  // RX pin 19 
  Serial2.begin(38400); // RX pin 17 
  
}

void loop()
{
  GPS1.update('$','\n'); // Start marker, End marker
  GPS2.update('!','\n');
}

Here is the code i used for the ethernet module :

#include <SPI.h>
#include <EthernetENC.h>
#include <EthernetUdp.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,21);
IPAddress RemoteIP(192,168,1,255);
const unsigned int RemotePort = 12345;    // The port that the program on the pc will listen on
const unsigned int localPort = 54321;      // local port to listen on (not to be used since arduino will only send data)

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup()
{
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);
}
void loop()
{  
  Udp.beginPacket(RemoteIP, RemotePort);
  Udp.write ("Test Data From Arduino\n");
  Udp.endPacket();
  delay (1000);  
}

To merge two sketches, copy one to the end of the other. Then merge the contents of the setup() and loop() functions so that you only have one of each.

#include "Builder.h"
#include <SPI.h>
#include <EthernetENC.h>
#include <EthernetUdp.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 21);
IPAddress RemoteIP(192, 168, 1, 255);
const unsigned int RemotePort = 12345;    // The port that the program on the pc will listen on
const unsigned int localPort = 54321;      // local port to listen on (not to be used since arduino will only send data)

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

Builder GPS1(&Serial1);
Builder GPS2(&Serial2);

void setup()
{
  Serial.begin(38400);  // USB port
  Serial1.begin(9600);  // RX pin 19
  Serial2.begin(38400); // RX pin 17
  // start the Ethernet and UDP:
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);
}

void loop()
{
  GPS1.update('$', '\n'); // Start marker, End marker
  GPS2.update('!', '\n');
  Udp.beginPacket(RemoteIP, RemotePort);
  Udp.write ("Test Data From Arduino\n");
  Udp.endPacket();
  delay (1000);
}

I understand your point.
That is not exactly what i had in mind.
I am looking for a way to use the EthernetENC.h library to transmit the UDP packages from inside my library Builder.h To be more specific , tx the upd package right after the Serial.println call . It is the data that are being send to the usb port that i also want to send to the ethernet module

Generally speaking, there are three different ways that an object of type Class B can "use" an object of type Class A.

  1. Class B contains a (usually private) data member of type Class A (aka Class B "HAS" a Class A object).

  2. Class B inherits from Class A (aka Class B "IS A TYPE OF" Class A object).

  3. The object of type Class A is instantiated externally and a reference (or pointer) to it is passed into Class B (aka Class B "KNOWS" a Class A object).

It sounds like the 3rd way is the way to go in my case. Yes ?

I typically pass a pointer to whatever resource objects I need into whatever object I'm working on. I guess that would be type (3) ?

-jim lee

I guess.
Ahh if only i culd understand how to do that... :frowning: