ATtiny88 sketch partil upload

ATtiny 88 dev board, uploading via USB, latest Ardunio IDE.
I can only partially upload a sketch.
I can install sketches like examples etc but when I try to upload the sketch below it will only allow me upload and run 3 moves.
If I add another move is says it has uploaded but the ATtiny busy light stays blinking and fails to run.
I can pick any 3 moves but 3 is the max that works.
Any ideas pse?
Eddy

#include <Stepper.h>  // Include the Arduino Stepper.h library

class Pause
{
public:
  constexpr Pause(unsigned long  milliseconds,
                  unsigned int   seconds = 0,
                  unsigned int   minutes = 0)
    : m_milliseconds{milliseconds + (seconds * 1000) + (minutes * 60000)}
  {};

  constexpr unsigned long  milliseconds() const {return m_milliseconds;};

private:
  unsigned long const  m_milliseconds;
};

struct Pin_Change
{
  uint8_t const  pin_number;
  uint8_t const  new_value;
};

enum Step_Direction {step_inwards = -1, step_outwards = 1};

struct Movement
{
  size_t const          number_of_pins_to_change_before;
  Pin_Change const      pin_changes_before[NUM_DIGITAL_PINS];
  Step_Direction const  step_direction;
  size_t const          steps_to_move;
  long const            speed_to_move_at;
  uint8_t const         travel_limit_input;
  size_t const          number_of_pins_to_change_after;
  Pin_Change const      pin_changes_after[NUM_DIGITAL_PINS];
  Pause const           pause_after_move;
};


void
setup()
{
  /****************************
   * Define the stepper motor *
   ***************************/
  constexpr uint8_t  motor_pins[] = {8, 10, 9, 11};
  Stepper            stepper_motor = Stepper{2048,
                                             motor_pins[0],
                                             motor_pins[1],
                                             motor_pins[2],
                                             motor_pins[3]};
  constexpr long default_step_speed{5};


  /*****************************
   * Define the limit switches *
   ****************************/
  constexpr uint8_t  home_limit_switch{7};
  constexpr uint8_t  max_travel_limit_switch{6};

  pinMode(home_limit_switch, INPUT_PULLUP);
  pinMode(max_travel_limit_switch, INPUT_PULLUP);


  /********************
   * Configure ouputs *
   *******************/
  digitalWrite(13, LOW);
  pinMode(13, OUTPUT);
  digitalWrite(3, LOW);
  pinMode(3, OUTPUT);
  digitalWrite(4, LOW);
  pinMode(4, OUTPUT);
  digitalWrite(5, LOW);
  pinMode(5, OUTPUT);


  /********************************
   * Define the movement sequence *
   *******************************/
  constexpr Movement  moves[] =
  {// Movement 1
   {1, {{13, HIGH}},                                  // 1 pin change
    step_outwards, 600, 15, max_travel_limit_switch, // Outward 600 steps, speed 15
    0, {},                                           // No pin changes
    { 0, 2}},                                        // 2 sec pause

   // Movement 2
   {1, {{3, HIGH}},                                  // 1 pin change
    step_outwards, 700, 3, max_travel_limit_switch,  // Outward 700 steps, speed 3
    0, {},                                           // No pin changes
    {500,  2}},                                      // 2.5 sec pause

   // Movement 3
   {3, {{5, HIGH}, {4, HIGH}, {13,LOW}},              // 3 pin changes
    step_inwards, 600, 10, home_limit_switch,        // Inward 600 steps, speed 10
    1, {{3, LOW}},                                   // 1 pin change
    {0, 5}},                                         // 5 sec pause

   // Movement 4
   {1, {{13, HIGH}},                                  // 1 pin change
    step_inwards, 0, 0, home_limit_switch,           // No steps
    0, {},                                           // No pin changes
    {750}},                                          // 0.75 sec pause

   // Movement 5
   {0, {},                                           // No pin changes
    step_inwards, 500, 10, home_limit_switch,        // Inward 500 steps, speed 10
    0, {},                                           // No pin changes
    {250, 2}},                                       // 2.25 sec pause

   // Movement 6
   {2, {{13,LOW}, {3, HIGH}},                         // 2 pin changes
    step_inwards, 700, 10, home_limit_switch,        // Inward 700 steps, speed 10
    1, {{5, LOW}},                                   // pin change
    {500, 2}},                                       // 2.5 sec pause

   // Movement 7
   {2, {{4, LOW}, {13, HIGH}},                        // 2 pin changes
    step_outwards, 500, 8, max_travel_limit_switch,  // Outward 500 steps, speed 8
    0, {},                                           // No pin changes
    {750,  3}},                                      // 3.75 sec pause

   // Movement 8
   {3, {{5, HIGH}, {4, HIGH}, {13, LOW}},            // 3 pin changes
    step_inwards, 800, 15, home_limit_switch,       // Inward 800 steps, speed 15
    3, {{5, LOW}, {4, LOW}, {3, LOW}},              // 3 pin changes
    { 0, 2}}};                                      // 2 sec pause

  constexpr size_t  number_of_moves{sizeof(moves)/sizeof(moves[0])};


  /*****************************
   * Run the movement sequence *
   ****************************/
  stepper_motor.setSpeed(default_step_speed);
  step_until_limit(stepper_motor, step_inwards, home_limit_switch);

  make_moves(stepper_motor, moves, number_of_moves);

  stepper_motor.setSpeed(default_step_speed);
  step_until_limit(stepper_motor, step_inwards, home_limit_switch);

  power_off_stepper(motor_pins);
}


void
loop()
{}


void
step_until_limit(Stepper&            stepper_motor,
                 unsigned int const  step_direction,
                 uint8_t const       travel_limit_input)
{
  while (HIGH == digitalRead(travel_limit_input))
  {
    stepper_motor.step(step_direction);
  }
}


void
make_moves(Stepper&        stepper_motor,
           Movement const  moves[],
           size_t const    number_of_moves)
{
  for (size_t  move_index = 0; number_of_moves > move_index; ++move_index)
  {
    make_move(stepper_motor, moves[move_index]);
  }
}



void
make_move(Stepper&  stepper_motor, Movement const &  move_to_make)
{
  change_pins(move_to_make.number_of_pins_to_change_before,
              move_to_make.pin_changes_before);

  move_steps_with_stop_limit(stepper_motor,
                             move_to_make.step_direction,
                             move_to_make.steps_to_move,
                             move_to_make.speed_to_move_at,
                             move_to_make.travel_limit_input);

  change_pins(move_to_make.number_of_pins_to_change_after,
              move_to_make.pin_changes_after);

  delay(move_to_make.pause_after_move.milliseconds());
}



void
change_pins(size_t  number_of_pins_to_change, Pin_Change const  pin_changes[])
{
  if (NUM_DIGITAL_PINS < number_of_pins_to_change)
  {
    number_of_pins_to_change = NUM_DIGITAL_PINS;
  }

  while(0 < number_of_pins_to_change)
  {
    --number_of_pins_to_change;
    digitalWrite(pin_changes[number_of_pins_to_change].pin_number,
                 pin_changes[number_of_pins_to_change].new_value);
  }
}



void
move_steps_with_stop_limit(Stepper&              stepper_motor,
                           Step_Direction const  step_direction,
                           size_t                steps_to_move,
                           long const            speed_to_move_at,
                           uint8_t const         travel_limit_input)
{
  if ((0 == step_direction) || (0 == steps_to_move) || (0 == speed_to_move_at))
  {
    return;
  }

  stepper_motor.setSpeed(speed_to_move_at);

  while ((0 < steps_to_move) &&
         (HIGH == digitalRead(travel_limit_input)))
  {
    stepper_motor.step(step_direction);
    --steps_to_move;
  }
}


void
power_off_stepper(uint8_t const  motor_pins[4])
{
  digitalWrite(motor_pins[0], LOW);
  digitalWrite(motor_pins[1], LOW);
  digitalWrite(motor_pins[2], LOW);
  digitalWrite(motor_pins[3], LOW);
}

A mega88 has 1k of RAM. It looks like your setup() function (in the code posted) is using somewhat more than 1k of local variables.

Because of the AVR's Harvard Architecture, "constexpr" is not going to be as much of a win as you're hoping for. Making moves[] global results in:

Sketch uses 3978 bytes (24%) of program storage space. Maximum is 16384 bytes.
Global variables use 1013 bytes (98%) of dynamic memory, leaving 11 bytes for local variables. Maximum is 1024 bytes.
Low memory available, stability problems may occur.

(and setup still has ~30 bytes of local variables and ~6 bytes of saved registers.)

avr-gdb /tmp/Arduino1.8.13Build/test_moves.ino.elf 
GNU gdb (AVR_8_bit_GNU_Toolchain_3.6.1_495) 7.8
  :
(gdb) print sizeof(moves)
$1 = 1000

using locally scoped constants may be good programming practice in general, but it prevents such memory-size errors from being detected at compile time, so it can be undesirable for small embedded processors. (Especially since there is no run-time check for such errors, nor any OS to report "segmentation error" or similar.)

You'll want to look at the use of PROGMEM to store your large constant data in flash instead of RAM.

I think I have a bigger problem.

Sketch uses 3772 bytes (62%) of program storage space. Maximum is 6012 bytes.
Global variables use 13 bytes of dynamic memory.

What “core” are you using for your mega8i?
With MCUDude’s “minicore” and the optiboot bootloader, you should have 7680 bytes for code.

Note that your initialized data already needs to be in flash, so “moving” it to PROGMEM will not affect your code size. Not much, anyway.

This is what I have installed. Is the MiniCore version any better?
As you can tell I am no expert but willing to learn.

https://forum.mhetlive.com/topic/47/mh-et-live-tiny88-16-0mhz

I have installed the MiniCore boards.
Tried programming the Tiny88 with blink sketch using USBasp.
I have tried all the variants.

Sketch uses 944 bytes (12%) of program storage space. Maximum is 7680 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 1015 bytes for local variables. Maximum is 1024 bytes.
avrdude: Expected signature for ATmega88 is 1E 93 0A
Double check chip, or use -F to override this check.
Failed programming: uploading error: exit status 1

Struggled with that board manager, found out it was the wrong one.
This one is the correct one for the ATtiny.
ATtinyCore
Still cannot upload sketch even thought it says it has memory left. Confused.

Sketch uses 2684 bytes (39%) of program storage space. Maximum is 6780 bytes.
Global variables use 9 bytes (1%) of dynamic memory, leaving 503 bytes for local variables. Maximum is 512 bytes.

Please plug in the device (will time out in 60 seconds) ...
Device is found!
connecting: 16% complete
connecting: 22% complete
connecting: 28% complete
connecting: 33% complete
Device has firmware version 2.2
Device signature: 0x1e9311
Available space for user applications: 6650 bytes
Suggested sleep time between sending pages: 7ms
Whole page count: 208 page size: 32
Erase function sleep duration: 1456ms
parsing: 50% complete
Erasing the memory ...
erasing: 55% complete
erasing: 60% complete
erasing: 65% complete
Starting to upload ...
writing: 70% complete
writing: 75% complete
writing: 80% complete
Starting the user app ...
running: 100% complete

Micronucleus done. Thank you!

Oh. Sorry. I had mis-read your CPU as "ATmega88", rather than "ATtiny88"

"Micronucleus" will use a larger (USB-capable, at least in theory) bootloader.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.