Struggling to learn to code (in C++)!

Hi folks, so I have resisted Arduinos for a long time now.. Too long in fact!

I have always programmed micros in Assembly, and I know it's long-winded but I think it is such a lovely language when you get to grips with it. C++ for Arduino though I am really struggling with it!!!

I suspect I always knew I'd struggle as I just don't get the sheer number of variables and other, what appears to be non-descript functions and symbols, assembly seems to be matter-of-fact, and self-descriptive once you know how the micro works...

But here I am, learning anyway.

Can anyone give me a pointer towards a guide that goes in to just a bit more detail, or at least can anyone explain how they got through the initial headache of trying to piece everything together in their head and actually start to understand what they could actually get away with when messing with the code?

If it helps I am doing a couple of things, I am playing with some beginners tutorials supplied by Arduino, but also DCS BIOS, this is an addon that allows your board to interact with a flight simulator from DCS.

Anyway, if anyone can show me the light, so to speak, and help me crack this nut I would be very greatful!

Thanks.

You don't need to learn it all at once. In fact, you can be fine forever, just learning a small subset of c++ that makes your life easier. Start with c and just add in the bits you like. Kinda' like a buffet.

Well, that's what I do..

-jim lee

Problem is, it isn't a language, it's many languages, depending on the processor family, often (as in real-life) with significant differences within families.

High-level languages remove a lot of that.

Hi,
I find this site handy for having a play with the basic CPP code
https://www.w3schools.com/cpp/
you can click on the "run example" links and experiment with each command

pretty sure that user alto777 will reply yelling "just 3% of all users find this easy to learn"

anyway I post it. Take a look into this tutorial:

Arduino Programming Course

It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.

best regards Stefan

That's funny because C++ seems to be matter-of-fact, and self-descriptive once you know how structure a program

1 Like

1. Let us start with your/mine favorite Assembly Language to blink LED connected at PB5-pin of ATmega328P MCU (not the one that is on the UNO Board). This program is created and assembled using ATmel Studio 7.0.

;continuously blink LED connected at PB5
.include "m328Pdef.inc"
		.cseg
		.org	$0000			;Boot location of ATmega328P that is not on UNO Board
RESET:	rjmp	START
	
		.org	$0040			;user program begins from here in the flash
START: ;----- stack initialize--------
		nop
		ldi		r16, 0xFF		; stack Top is at 0x08FF
		out		spl, r16
		ldi		r16, 0x08
		out		sph, r16

PRTBINIT:;----- Port-B direction------------
		ldi		r16, 0xFF		; 1111 1111
		out		ddrb, r16		; all Port-B pins are output
					
BLINK:	;----Blink LED at PB5-pin -------------
		sbi		portb, pb5			; LED is ON
		rcall	DELAY
		rcall	DELAY
		rcall	DELAY
		
		cbi		portb, pb5			; LED is OFF
		rcall	DELAY    ; calling DELAY function for 3-time makes approx 1-sec delay.
		rcall	DELAY
		rcall	DELAY
       	rjmp	BLINK				; repeat blink

;------------Time Delay Function--------
DELAY:	ldi		r17, 255
cagain:	ldi		r18, 255
magain:	dec		r18
		brne	magain
		dec		r17
		brne	cagain
		ret
;--------------------------
		.exit

2. Let us convert the program of Step-1 using C-codes using Arduino IDE. This program will blink L (built-in LED) of Arduino UNO Board. L is connected at DPin-13 (PB5-pin) of the ATmega328P MCU of the UNO Board.
(1) An Arduino Sketch begins with two functions as shown below and the program execution always begins from the setup() function and then enters into the loop() function.

void setup()
{
    
}

void loop()
{

}

(2) The tasks that are executed only once or for a number of times are kept in the setup() function. Accordingly, the codes for setting the direction of Port-B will be in the setup() function. The Arduino/C code for the 2-line ASM codes of Step-1 (that makes Port-B output) is:

DDRB = 0xFF;     //all IO lines are output 
or
pinMode(13, OUTPUT);    //only PB5 (DPin-13) is output

(3) The tasks that are executed repeatedly are kept in the loop() function. Accordingly, the codes for blinking L will be in the loop() function. The Arduino/C code for the ASM codes of Step-1 to ON/OFF L are:

digitalWrite(13, HIGH);   //L is ON
delay(1000);      //1-sec delay using built-in function of Arduino IDE
digitalWrite(13, LOW);     //L is OFF
delay(1000);

3. The final Arduino Sketch/Program is:

void setup()
{
    //DDRB = 0xFF;     //all IO lines are output 
    //or
    pinMode(13, OUTPUT);    //only PB5 (DPin-13) is output
}

void loop()
{
    digitalWrite(13, HIGH);   //L is ON
    delay(1000);      //1-sec delay using built-in function of Arduino IDE
    digitalWrite(13, LOW);     //L is OFF
    delay(1000);
}

4. Lest us re-write the program of Step-3 using C++ OOP syntaxes.
To follow the codes of this Section, one needs to understand the meanings of the following concepts:
(1) class keyword
(2) user-defined data type
(3) object
(4) method
(5) private
(6) protected

Remark: Compare sketches of Step-3 and Step-1 to figure out which one is user-friendly though the Engineers do not dislike ASM Programming.

1 Like

well the blink the LED-code is waaaay toooo simple to do a serious comparison.
I have coded some assembler for 6502 (if you remember the chip) and for the parallax propeller-chip (32bit, real parallel execution in a 8 core-chip already back in 2006, conditional execution of each ASM-command depending on two flags set/cleared)

Let's see how you are doing something like a webserver in pure ASM. You will be half way up to C++ using a lot of pre-programmed ASM-subroutines.

best regards Stefan

1. For the beginners and even for myself, I follow what the Albert Einstein has said:
"The wise man starts from the basic (simple and elementary) and then gradually moves to the complex one."

2. How is it to study the following 8086 based ASM program (I created in 1996) and C based Program in the computation of 5! (factorial of 5) for comparison?

**8086 Assembly Program to compute 5!**  Use MicroTalk-8086 trainer (Fig-1) and demonstrate a Recursive Procedure by calculating the factorial of a number (up to 5 decimal). The result of the factorial will be in hex. The value will be displayed at positions D2D1 positions of the trainer. The remaining digit positions of the display would remain blank. Your task is to draw ASM codes, Flow Chart and Stack diagram.

; Data Value
(00475) (0074h) = xxxx (upto 0005) is to be entered first by the user

;Execution starts
ML1:01600 - BC FE FF		: mov	sp, 0FFFEh	; stcak top
	01603 – BB 00 04		: mov	bx, 0400h	; bx is a pointer
	01606 – 90 90 90		: nops

ML2:01609 – 81 EC 04 00	: sub 	sp, 0004h	; keeping four RAM locations to hold X!
	0160F – 8B 47 74		: mov	ax, [bx+74h]	; number is loaded into ax-register 

ML3:01612 – 50			: push	ax			; 1st factor is saved onto stack

ML4:01613 – 9A 66 16 00 00	: call	FACTO(01666h)	; get next factor if there is any

ML5:01618 -; the factorial of the contents of memory locations (00475)(00474) is at 
; memory locations (0FFFD – 0FFFA). Get the results from these locations and 
; display it at D4D-D1 positions of the MicroTalk-8086 trainer. D9-D5 
; positions will remain blank.			

	01618 - BB 00 04		: mov	bx, 0400h
	0161B – BD FA FF		: mov	bp, 0FFFAh
	0161E – 90			: nop
	0161F – 90			: nop
	01620 – 8B 46 00		: mov	ax, [bp+00h]			; get x! from (0FFFB, 0FFFA) 
	01623 – 89 47 4E		: mov	WORD PTR [bx+4Eh], ax	; put into T3 of reserved RAM
	01626 – 8B 46 02		: mov	ax, [bp+02h]			; get X! from (0FFFD, 0FFFC)
	01629 – 89 47 4F		: mov	WORD PTR [bx+4Fh], ax	;
	0162C – 9A 7C F4 00 F0	: call	SUR8 (0F47c)			; convert packed hex to cc-code
	01631 – C7 47 44 00 00	: mov	WORD PTR [bx+44h], 0000h	; blank D4D3 display
	01636 – C7 47 46 00 00	: mov	WORD PTR [bx+46h], 0000h	; blank D6D6 display
	0163B – C7 47 48 00 00	: mov	WORD PTR [bx+48h], 0000h	; blank D8D7 display
	01640 – C7 47 4A 00 00	: mov	WORD PTR [bx+4Ah], 0000h	; blank D9 display
	01645 – 9A B6 FF 00 00	: call	SUR3 (0FFB6h)			; transfer cc-code to display

ML6:0164A – EA 4A 16 00 00	: jmp	ML6 (0164A)			; done, loop here

;FACTO Subroutibe
SR1:01660 – 8B EC			: mov	bp, sp		; user can’t use sp as a pointer
	01662 – 8B 46 04		: mov	ax, [bp+04h]	; get the number x passed from MLP

SR2:01665 – 3D 01 00		: cmp	ax, 0001h	; check if x = 1

SR3:01668 – 75 0F			: jne	DETER (01679)	; if x>1, determine (x-1)

SR4:0166A – C7 46 06 01 00	: mov	[bp+06h], 00001h	; x = 1, so, save x! = 1
	0166F – C7 46 08 00 00	: mov	[bp+08h], 0000h	;

SR5:01674 – EA 96 16 00 F0	: jmp	EXIT (01696)		; factorial process is end

; DETER Subroutine
SR6:01679 – 81 EC 04 00	: sub	sp, 0004h	; 
	0167D – 48			; dec	ax

SR7:0167E – 50			: push	ax

SR8:0167F – 9A 60 16 00 00	: call	FACTO		; recursive call

SR9:016684 – 8B EC		: mov	bp, sp

SR10:01686 – 8B 46 02		: mov	ax, [bp+02h]
SR11:01689 – F7 66 0A		: mul	WORD PTR [bp+0Ah]	; 16-bit multiply, 

SR12:0168C – 89 46 0C		: mov	[bp+0Ch], ax
	 0168F – 89 46 0E		: mov	[bp+0Eh]

SR13: 01692 – 81 C4 06 00	: add	sp, 0006h

SR14: 01696 – CB			; ret		

Stack Diagram/Data Structure for the above Recursive ASM program

//===================================================================
C Program to compute 5!

factr(n)
	{
		if (n ==1)
			factorial = 1;
		else
			factorial = n*factr(n-1);
	}

In fact, for n=5, n! = 5x4x3x2x1. In the above c-codes, we observe that the program works in the following ways:
(1) Get n =5 and save (K5 = 5 and saved in locations 0FFF8, 0FFF9)
(2) Get (n-1) = 4and save K4 = 4
(3) Get ((n-1)-)) = 3 and save K3=3
(4) Get n-3 = 2 and save K2=2
(5) Get n-4 =1 and save K1 =1
(6) Now the statement:

if (n==1)
   Factorial =1

Is executed and save 1! =00001h at locations 0FFD2h – 0FFD5h

(7) The stack structure is arranged in such a way so that the same program codes could be repetitively used to get the result:
1h x 2h = 2h x3h = 6hx4h = 18hx5h = 78h = 120

Flow Chart for the Recursive Codes of the above C-Routine to compute 5!
1420A

MicroTalk-8086 Trainer


Figure-1:

Thanks for the responses, folks. I do understand that nearly everything is simplified within C, that I get, but I think that is also the problem from my perspective. However, I also think I am probably making it more difficult than needs be, I am approaching this problem like I should be able to adapt immediately, and well that is a bit silly I guess.

Some good links there so thanks,

I'll plod on with the tutorials and I am sure in a months time I'll be wondering why I made all the fuss!

If you come from assembler the compiler explorer might be a reassuring tool for you. It compiles on the fly and shows the generated assembler. You can also see the effect of different compiler flags:

Here an example calculating a Gaussian sum. Change the optimizing level from -O0 to -O2 to see what a modern compiler can do :slight_smile:

some have said C is just PDP-11 assembler. pointers can be used to directly access memory mapped I/O as well as implement algorithms using data structures.