Two issues with a program can anyone Help if possible

Good Morning all
I wounder if Anyone is available to look of a program and advise please
I have come into a project Three quarters though My predecessor had started the project then left but left Leaving me with loads of issues machine base and program base

The machine is controlled by a Nano basic but the program has two issues firstly the project spec stated length of paper from 250mm to 4m the but the program is operating 250mm to 2m as stated line 244
Also a very strange fault if the machine runs out of paper the start button needs to be pressed 3 times before normal operation
If Anyone has any ideas or can see any other possible issues will be gratefully appreciated

Unfortunately my background is Machine automation with plc controllers with ladder and scl and sql and robotics And very new to Arduino

//BLUEBOARD NO RUNON TIMER (B7)
// NOTES : STANDARD MACHINE CODE WITH JOG SWITCH RUN ON TIMER AND CUT SPEED CONTROL ON FAULT POT.(V4)
// The ardunio libraries have a timer limitation, in that we need the processor timer0/1 for PWM's and it uses the timer0/1 for delay/sleep functions
// The functions will still work, but just at the wrong speed/time.
// To tackle this there are defines that equate to real time periods
//
// Set Terminal to 115200

// A #define is used by the compiler, where ever the defined name appears in the code the value assigned is inserted
// Meaning you can define it in one place and only need to change it once. Reducing errors
// We  use them here to set pin numbers. Pin numbers relate to the port pin of the processor (Not physical chip pin numbers)

#define LOAD_SPEED          160             // Speed used when loadSwitch is pressed. Max 255

#define PIN_AIN1            5               // 
#define PIN_AIN2            6               // 
#define PIN_FAULT_OUT       7               // 
#define PIN_BIN1            9               // 
#define PIN_BIN2            10              // 

#define PIN_OC_POT          A6              // Analog input, On board Pot
#define PIN_SPD_POT         A5              // Analog input, On board Pot

#define FEED_BASE           125              // max 255
#define FEED_RATE           15               // step change per task interval (50mS) - max 255, DO NOT make larger than FEED_BASE
#define MAX_FEED_SPEED      255              // max 255, lower val = lower speed

#define CUT_BASE            180              // max 255
#define CUT_RATE            10               // step change per task interval (50mS) - max 255, DO NOT make larger than CUT_BASE
#define CUT_BRAKE           1                // 1 = BRAKE, 0 = NO BRAKE       
#define MAX_CUT_SPEED       249              // max 255, lower val = lower speed 
#define SLOW_CUT_SPEED      180              // max 255, lower val = lower speed    
#define REV_CUT_SPEED       180              // max 255, lower val = lower speed              

#define RUN_ON_TIME         0                //time in 50mS increments

// The DRV IC is connected via SPI and uses the following pins :
#define DRV_SPI_CS_PIN      8               // SPI CS Line
#define DRV_SPI_MOSI        11              // SPI Master out slave in
#define DRV_SPI_MISO        12              // SPI Master in slave out
#define DRV_SPI_CLK         13              // SPI Clock
#define DRV_RST             4               // Reset control input to DRV
#define DRV_SLEEP           3               // Sleep control input to DRV
#define DRV_FAULT           2               // Fault output from DRV

#define FAULT_PERIOD        10              // number of 50mS periods
#define MAX_FAULTS          10              // maximum faults allowed in above time before lockout

// The following is a list of register numbers in the DRV8704 IC
// Refer to the data sheet : http://www.ti.com/lit/ds/symlink/drv8704.pdf
// For details of what each register will do

#define DRV_REG_CTRL        0x00             // 
#define DRV_REG_TORQUE      0x01             // 
#define DRV_REG_OFF         0x02             // 
#define DRV_REG_BLANK       0x03             // 
#define DRV_REG_DECAY       0x04             // 
#define DRV_REG_RESERVED    0x05             // 
#define DRV_REG_DRIVE       0x06             // 
#define DRV_REG_STATUS      0x07             // 

// Read messages have the top bit set. Write messages do not
#define DRV_READ_MASK       0x80             // 
#define DRV_WRITE_MASK      0x00             // 

// This is an array, we use this to store a copy of the DRV registers
uint16_t DrvRegisterCache[8];

typedef enum SYS_STATE_T
{
  SYS_STATE0 = 0,
  SYS_STATE1,
  SYS_STATE2,
  SYS_STATE3,
  SYS_STATE4
} SYS_STATE_T;

SYS_STATE_T CurrentState = SYS_STATE0;

// Store the Previous no of MS
unsigned long PrevMS = 0;

// Interval, as timer0 has been addjust for the PWM, the millis() does not provide MS timing,
// these interval values help convert the new time base to a known one
const long OneSecond_Interval = 64100;
const long HundredMS_Interval = 6410;
const long TenMS_Interval = 641;

// Select the sheduler tick interval
const long TickInterval = TenMS_Interval;

// These varibles will store the ADC value from each pot 0 to 1023
uint16_t OcPotVal;
uint16_t SpdPotVal;

char demandClear;

bool minLengthReached = true;
bool Active = false;
bool stopping = false;      //Variable used to determine whether motors have just run, and need to stop.
int lengthNeeded = 0;       //Variable used to track if a length is needed
int iteration = 0;          //Used to keep track of how many times the loop iterates, used for timing between motor stopping.
int potIteration = 0;       //used to keep track of loop iterations for mode 2.
int potLength = 0;
int lastState = 0;
int Iteration2 = 0;
int noPaper = 0;

// -----------------------------------------------------------------------------------------------------------------------------

// ---------------------------------------------------------------
// Set up the interface to the DRV
// ---------------------------------------------------------------
void DRV_Init ( void )
{
  pinMode(DRV_FAULT, INPUT);
  pinMode(DRV_SLEEP, OUTPUT);
  pinMode(DRV_RST, OUTPUT);

  pinMode(DRV_SPI_CS_PIN, OUTPUT);
  pinMode(DRV_SPI_MOSI, OUTPUT);
  pinMode(DRV_SPI_MISO, INPUT);
  pinMode(DRV_SPI_CLK, OUTPUT);

  // Take the chip out of reset and wake it up..
  digitalWrite(DRV_SLEEP, HIGH);
  digitalWrite(DRV_RST, LOW);

  SPI.begin();
}

// ---------------------------------------------------------------
// Write to the DRV
// ---------------------------------------------------------------
void DRV_Write ( byte reg, uint16_t newValue )
{
  uint8_t tempOut;

  SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));

  // take the SS pin high to select the chip:
  digitalWrite(DRV_SPI_CS_PIN, HIGH);

  // We dont want the top four bits, DRV registers are 12bit
  newValue = newValue & 0x0FFF;

  // Send the DRV the address and value via SPI:
  tempOut = ( (reg << 4) | DRV_WRITE_MASK );
  tempOut = tempOut | (uint8_t)(( newValue >> 8 ) & 0x000F);
  SPI.transfer( tempOut );

  tempOut = (uint8_t)( newValue & 0x00FF);
  SPI.transfer( newValue );

  // take the SS pin low to de-select the chip:
  digitalWrite(DRV_SPI_CS_PIN, LOW);
  SPI.endTransaction();
}

// ---------------------------------------------------------------
// Read from the DRV
// ---------------------------------------------------------------
uint16_t DRV_Read ( byte reg )
{
  uint16_t result = 0;
  SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));

  // take the SS pin high to select the chip:
  digitalWrite(DRV_SPI_CS_PIN, HIGH);

  // To Read you must send the register value shifted up
  // With bit7 set
  result = SPI.transfer( (reg << 4) | DRV_READ_MASK );
  result = result << 8;
  result |= SPI.transfer(0x00);
  result &= ~0x8000;

  // take the SS pin low to de-select the chip:
  digitalWrite(DRV_SPI_CS_PIN, LOW);
  SPI.endTransaction();

  return ( result );
}

// ---------------------------------------------------------------
// PWM_Init - Set up the PWM output
// ---------------------------------------------------------------
void PWM_Init ( void )
{
  // PWM Setup, the configures the chips timer directly
  // WARNING : this will interfer with the ardunio sleep/delay library so can not be used at the same time..
  OCR0A = 0x00;
  OCR0B = 0x00;
  TCCR0A = 0b10100011;
  TCCR0B = 0b00000001;
  OCR1AH = 0x00;
  OCR1BH = 0x00;
  OCR1AL = 0x00;
  OCR1BL = 0x00;
  TCCR1A = 0b10100001;
  TCCR1B = 0b00001001;
}

// ---------------------------------------------------------------
// setup - Called by the Ardunio library first
// ---------------------------------------------------------------
void setup()
{
  // put your setup code here, to run once:
  // open the serial port at 115200 bps
  // Use the terminal to help debug your code..
  //Serial.begin(115200);

  // Set up the DRV interface/pins
  DRV_Init();

  pinMode(PIN_FAULT_OUT, OUTPUT);
  pinMode(PIN_AIN1, OUTPUT);
  pinMode(PIN_AIN2, OUTPUT);
  pinMode(PIN_BIN1, OUTPUT);
  pinMode(PIN_BIN2, OUTPUT);
  pinMode(7, INPUT_PULLUP);
  //pinMode(A2, INPUT_PULLUP);
  //pinMode(A3, INPUT_PULLUP);
  //pinMode(A4, INPUT_PULLUP);




  digitalWrite(PIN_BIN1, LOW);
  digitalWrite(PIN_BIN2, LOW);
  digitalWrite(PIN_FAULT_OUT, LOW);

  PWM_Init();
}

// ---------------------------------------------------------------
// InputLoop - Process the inputs and action the pwm output
// to the DRV
// ---------------------------------------------------------------
void InputLoop ()
{
  static int stepsPer = 22;            //This is how many steps of the potentiometer equals 50ms of motor running time. Use this to adjust length of paper.
  //For example, 5 steps will mean if pot value reads 20, motors will run for 20/5 * 50ms = 200ms. Increasing this value will mean less length for the same pot reading, and vice versa for decreasing.

  static int minLength = 15;          //This is how many 50ms motor will run regardless of pot reading. Used mostly when pot is a low value (e.g. 20) and thus motors run for 100 ms, which is not long enough.

  int footPedal = analogRead(A1);
  int loadSwitch = analogRead(A0);
  int potVal = analogRead(A3);
  //decide which mode based on potentiometer's built-in switch.
  int mode;
  if (analogRead(A4) < 20) {
    mode = 1;
  }
  else {
    mode = 2;
  }
  int paperEye = analogRead(A2);

  static int speed = 0;

  //calculate pot input into length
  potVal = potVal / stepsPer;
  potVal = potVal + 10;



  //MODE 1
  if (mode == 1) {

    //if loadSwitch is pressed and the motors are not in the process of stopping, run motors at speed defined in LOAD_SPEED
    if (loadSwitch < 650 && !stopping) {
      OCR1AL = LOAD_SPEED;
      OCR1BL = 0x00;
      OCR0A = LOAD_SPEED;
      OCR0B = 0x00;
    }

    //if footPedal is high (>4v), run both motors forward at full speed, with acceleration ramp
    else if (footPedal < 650 || !minLengthReached) {

      if (Iteration2 < minLength) {
        minLengthReached = false;
        Iteration2 ++;
      }
      else {
        minLengthReached = true;
      }
      //make sure there is enough room to ramp up
      if (speed < (MAX_FEED_SPEED - FEED_RATE))
      {
        speed += FEED_RATE;
      }
      else
      {
        speed = MAX_FEED_SPEED;
      }

      //needs to stop when pedal is released.
      stopping = true;
      //set motors to speed as changed when ramping up (the above if statement)
      OCR1AL = speed;
      OCR1BL = 0x00;
      OCR0A = speed;
      OCR0B = 0x00;
    }

    //if motors need to stop, and speed is greater than stopped speed (FEED_BASE)(this is not strictly necessary, just sanity check), stop motors with delay between motors.
    else if (stopping) {

      //brake motor 1
      OCR1AL = 0xFF;
      OCR1BL = 0xFF;

      //delay
      if (iteration < 5 + 1) { //Change this number to change the delay betweens stopping. Each iteration takes 50ms, so a value of 6 means that 6*50ms = 300ms.
        iteration ++;
      }

      else {
        //reset iteration counter
        iteration = 0;
        //brake motor 2
        OCR0A = 0xFF;
        OCR0B = 0xFF;
        //set speed to off
        speed = FEED_BASE;
        //stopping is complete, no longer needs to stop
        stopping = false;
        minLengthReached = true;
        Iteration2 = 0;
      }
    }

    //else feed is off
    else
    {
      OCR1AL = 0x00;
      OCR1BL = 0x00;
      OCR0A = 0x00;
      OCR0B = 0x00;
      speed = FEED_BASE;
      minLengthReached = true;
      Iteration2 = 0;
      Active = false;
    }
  }



  //MODE 2
  if (mode == 2) {

    //if loadSwitch is pressed and the motors are not in the process of stopping, run motors at speed defined in LOAD_SPEED
    if (loadSwitch < 650 && !stopping && lengthNeeded == 0) {
      OCR1AL = LOAD_SPEED;
      OCR1BL = 0x00;
      OCR0A = LOAD_SPEED;
      OCR0B = 0x00;
    }

    //if footpedal is high (>4v), do logic to switch Active true or false.
    else if (footPedal < 650) {

      if (lastState == 0) {
        if (Active) {
          Active = false;
          lengthNeeded = 1;
          stopping = true;
        }
        else {
          Active = true;
        }
        lastState = 1;
      }
    }

    //if a length is needed, run motors for time based on potentiometer input
    else if (lengthNeeded == 1 && Active) {

      noPaper ++;

      if (potIteration < potVal + 1) {
        if (speed < (MAX_FEED_SPEED - FEED_RATE))
        {
          speed += FEED_RATE;
        }
        else
        {
          speed = MAX_FEED_SPEED;
        }

        //needs to stop when pedal is released.
        //stopping = true;
        //set motors to speed as changed when ramping up (the above if statement)
        OCR1AL = speed;
        OCR1BL = 0x00;
        OCR0A = speed;
        OCR0B = 0x00;
        potIteration ++;
      }

      else {
        lengthNeeded = 0;
        stopping = true;
        potIteration = 0;
      }

      //change the less than thumber for potIteration to change the time it stops (number of 50ms so 20 = one second. However, if the potVal is less than this number, this function pretty much becomes irrelevant. 
      if (potIteration > 20 && paperEye > 100 ) {
        lengthNeeded = 0;
        stopping = true;
        potIteration = 0;
        Active = false;
      }

    }

    //if motors need to stop, stop motors with delay between motors.
    else if (stopping) {

      //brake motor 1
      OCR1AL = 0xFF;
      OCR1BL = 0xFF;

      //delay
      if (iteration < 3 + 1) { //Change this number to change the delay betweens stopping. Each iteration takes 50ms, so a value of 6 means that 6*50ms = 300ms.
        iteration ++;
      }

      else {
        //reset iteration counter
        iteration = 0;
        //brake motor 2
        OCR0A = 0xFF;
        OCR0B = 0xFF;
        //set speed to off
        speed = FEED_BASE;
        //stopping is complete, no longer needs to stop
        stopping = false;
        //lengthNeeded = 0;
        //lastState = 0;
      }
    }

    //if lengthNeeded equals 0 and paper eye detects empty space, and is Active, call lengthNeeded 1
    else if (lengthNeeded == 0 && paperEye > 100 && Active) {
      lengthNeeded = 1;


    }

    //else feed is off
    else
    {
      OCR1AL = 0x00;
      OCR1BL = 0x00;
      OCR0A = 0x00;
      OCR0B = 0x00;
      speed = FEED_BASE;
      lastState = 0;
    }
  }

  if (paperEye < 100) {
    noPaper = 0;
  }

  //change the less than thumber for potIteration to change the time it stops (number of 50ms so 20 = one second.
  if (noPaper > 20 && paperEye > 100) {
    lengthNeeded = 0;
    stopping = true;
    potIteration = 0;
    Active = false;
    noPaper = 0;
  }
}
// ---------------------------------------------------------------
// PrintHex - Takes the supplied "num" and prints the value in
// readable hex over the serial port
// ---------------------------------------------------------------
void PrintHex ( uint16_t num )
{
  char tmp[16];
  char format[128];

  sprintf(format, "0x%%.%dX", 4);

  sprintf(tmp, format, num);
  //Serial.print(tmp);
}

// ---------------------------------------------------------------
// ReadAllDrvRegisters - Read all of the DRV registers in to RAM
// ---------------------------------------------------------------
void ReadAllDrvRegisters ( void )
{
  // Read all of the DRV registers in to memory
  DrvRegisterCache[DRV_REG_CTRL] = DRV_Read(DRV_REG_CTRL);
  DrvRegisterCache[DRV_REG_TORQUE] = DRV_Read(DRV_REG_TORQUE);
  DrvRegisterCache[DRV_REG_OFF] = DRV_Read(DRV_REG_OFF);
  DrvRegisterCache[DRV_REG_BLANK] = DRV_Read(DRV_REG_BLANK);
  DrvRegisterCache[DRV_REG_DECAY] = DRV_Read(DRV_REG_DECAY);
  DrvRegisterCache[DRV_REG_DRIVE] = DRV_Read(DRV_REG_DRIVE);
  DrvRegisterCache[DRV_REG_STATUS] = DRV_Read(DRV_REG_STATUS);
}

// -----------------------------------------------------------------
// PrintAllDrvRegisters -  This function will print out the cached
// registers to the terminal
// -----------------------------------------------------------------
void PrintAllDrvRegisters ( void )
{
  // Serial.print("DRV Register 0 (CTRL) : ");
  PrintHex(DrvRegisterCache[DRV_REG_CTRL]);
  //  Serial.print("\r\n");

  // Serial.print("DRV Register 1 (DRV_REG_TORQUE) :");
  PrintHex(DrvRegisterCache[DRV_REG_TORQUE]);
  // Serial.print("\r\n");

  // Serial.print("DRV Register 2 (DRV_REG_OFF) :");
  PrintHex(DrvRegisterCache[DRV_REG_OFF]);
  // Serial.print("\r\n");

  // Serial.print("DRV Register 3 (DRV_REG_BLANK) :");
  PrintHex(DrvRegisterCache[DRV_REG_BLANK]);
  // Serial.print("\r\n");

  // Serial.print("DRV Register 4 (DRV_REG_DECAY) :");
  PrintHex(DrvRegisterCache[DRV_REG_DECAY]);
  // Serial.print("\r\n");

  // Serial.print("DRV Register 6 (DRV_REG_DRIVE) :");
  PrintHex(DrvRegisterCache[DRV_REG_DRIVE]);
  // Serial.print("\r\n");

  // Serial.print("DRV Register 7 (DRV_REG_STATUS) :");
  PrintHex(DrvRegisterCache[DRV_REG_STATUS]);
  // Serial.print("\r\n");
}

// ---------------------------------------------------------------
// ScheduleTicked - Using the Millisecond count provided by Arduio
// provide time base for scheduled code
// ---------------------------------------------------------------
bool ScheduleTicked ( void )
{
  unsigned long currentMS = millis();
  bool ticked = false;
  int difference;

  // We will constantly compare the current MsCounter with the previous to see if we have reached the interval
  // This is far better than using delay()
  // Also note due to the PWM freq requirements timer0 has been modified meaning the millis() provided value is not in ms
  // OneSecondInterval is calculated at the current pwm freq to give you one second timing..
  if ((currentMS - PrevMS) >= TickInterval)
  {
    PrevMS = currentMS;
    ticked = true;
  }
  else if (PrevMS > currentMS)
  {
    // The currentMS has rolled over
    difference = (0xFFFFFFFF - PrevMS) + currentMS;
    if ( difference >= TickInterval)
    {
      PrevMS = currentMS;
      ticked = true;
    }
  }

  return ( ticked );
}


bool toggle = false;
bool enableNextTime = true;

// ---------------------------------------------------------------
// loop is the Ardunio Main loop
// it will contastanly call this function..
// Process you inputs, make decisions then leave to repeat..
// ---------------------------------------------------------------
void loop()
{
  bool ticked = ScheduleTicked();
  static char fltCount = 0;
  static char fltTimer = 0;
  static char faultPending = 0;

  if (ticked)
  {
    ticked = false;

    // You can now schedule your code against a known time base (the interval)
    // NOTE : If the interval is too short the code execute might take longer to run than the TickInterval period
    //toggle = !toggle;
    //digitalWrite(PIN_FAULT_OUT, toggle);

    // State machine example ..
    // Your product may do different things at different times
    // Sometimes it helps to break this down in to states
    switch ( CurrentState )
    {
      case SYS_STATE0 :

        // Read all of the DRV Registers
        ReadAllDrvRegisters();

        //next state
        CurrentState = SYS_STATE1;

        break;

      case SYS_STATE1 :

        // Print out registers so we can check them
        PrintAllDrvRegisters();

        //next state
        CurrentState = SYS_STATE2;

        break;

      case SYS_STATE2 :

        // Capture input demands and set PWM outputs
        InputLoop();

        //next state
        CurrentState = SYS_STATE3;

        break;

      case SYS_STATE3 :

        // Read the input pots
        OcPotVal = analogRead(PIN_OC_POT);
        SpdPotVal = analogRead(PIN_SPD_POT);

        //print out ADC values
        //Serial.print("OC Pot : ");
        //Serial.print(OcPotVal);
        //Serial.print(" - SPD Pot : ");
        //Serial.print(SpdPotVal);
        // Serial.print("\r\n");

        // next state
        CurrentState = SYS_STATE4;

        break;

      case SYS_STATE4 :

        // Write to the DRV chip
        if ( enableNextTime )
        {
          //Serial.println("Enable Motor (DRV)");
          // BIT0 set to enable the motor
          DRV_Write( DRV_REG_CTRL, 0x0201 );
          DRV_Write( DRV_REG_BLANK, 0x00FF );
          //DRV_Write( DRV_REG_DRIVE, 0x0FAE );
          DRV_Write( DRV_REG_DRIVE, 0x0FAD );       //OCP trip set to 89A (500mV @ Rds of 5.6mR)
        }
        else
        {
          //Serial.println("Disable Motor (DRV)");
          // BIT0 cleared to disable the motor
          DRV_Write( DRV_REG_CTRL, 0x0300 );
        }

        //enableNextTime = !enableNextTime;

        //if there was a fault to clear from last time and we haven't faulted too many times then clear the fault to allow retry
        if ((faultPending) && (demandClear))
        {
          DRV_Write( DRV_REG_STATUS, 0x0000);
          faultPending = 0;
        }

        //if all demands have been removed then clear the fault counter
        if (demandClear)
        {
          fltCount = 0;
        }

        //if the fault line is active (low) then flag up a fault for next time round
        if (digitalRead(DRV_FAULT) == 0)
        {
          fltTimer = 0;
          fltCount++;

          //prevent overflow of counter
          if (fltCount >= MAX_FAULTS)
          {
            fltCount = MAX_FAULTS;
          }

          faultPending = 1;

        }

        /*
                //clear fault counter after timeout
                if(fltTimer++ > FAULT_PERIOD)
                {
                  fltCount = 0;
                  fltTimer = 0;
                }

                //check for driver fault and clear
                if(digitalRead(DRV_FAULT) == 0)
                {
                  fltTimer = 0;
                  fltCount++;

                  //if we havent exceeded max faults then retry
                  if(fltCount < MAX_FAULTS)
                  {
                    DRV_Write( DRV_REG_STATUS, 0x0000);
                  }

                  //else prevent overflow of counter
                  else
                  {
                    fltCount = MAX_FAULTS;
                  }
                }

        */
        // Back to the begining!
        CurrentState = SYS_STATE0;

        break;

    }

  }
  else
  {
    // some code you might want to run all the time as fast as possible
    // if so put it here ..
    // NOTE : again if the code here takes a long time to execute it can delay the scheduled code..
  }
}

type or paste code here

You have to avoid using timer0 only. Timer1 and Timer2 can be used freely since you are not explicitly using any libraries.

Maybe you can start by describing what hardware this Nano is controlling so that people trying to help have an overview of the whole thing.

@hollywood2395 ,

Topic moved to programming questions as that seems more appropriate.

Thank you Perry

1 Like

Add in scetch

#include <SPI.h>

Don't have time at the moment to go throught the entire code, particularly since I'll have to look up the register commands to see what is being done with the PWM, but I do see a few odd things.

There are a couple of places where SPI is used to communicate with a DRV chip (presumably a motor driver?). The chip is de-selected before endTransmission() is called.


  // take the SS pin low to de-select the chip:
  digitalWrite(DRV_SPI_CS_PIN, LOW);
  SPI.endTransaction();

There is also no #include statement for the SPI library header file.

As long as currentMS and PrevMS are both unsigned integers, there is no need for the code under "else", unsigned subtraction will work properly to give the correct difference.

  if ((currentMS - PrevMS) >= TickInterval)
  {
    PrevMS = currentMS;
    ticked = true;
  }
  else if (PrevMS > currentMS)
  {
    // The currentMS has rolled over
    difference = (0xFFFFFFFF - PrevMS) + currentMS;
    if ( difference >= TickInterval)
    {
      PrevMS = currentMS;
      ticked = true;
    }
  }

It is utterly ridiculous to use 128 bytes of ram for a buffer to store the format text when it only occupies 7 bytes, and there is no need to dynamically generate format anyway.

void PrintHex ( uint16_t num )
{
  char tmp[16];
  char format[128];

  sprintf(format, "0x%%.%dX", 4);

  sprintf(tmp, format, num);
  //Serial.print(tmp);
}

You sort of jumped right into the problems with no background info. What is "the machine" and what is it supposed to do? It is much easier to troubleshoot code when you know what the intended result is.

Thank you David I do appreciate your time and experience

If you can support when your free I would be greatly appreciated

Kindest regards

Simon

Hi delta

Very sorry yes the machine is a desk top machine that takes a 300mm roll and compresses it into 50x50 for packaging using two motors driving wheels to drive the paper through the machine and the rear motor stops at the length and the front wheel to pull the paper apart at set lengths

Hope this helps

Kindest regards

Simon.

regarding the length, I see

  static int stepsPer = 22;            //This is how many steps of the potentiometer equals 50ms of motor running time. Use this to adjust length of paper.
  //For example, 5 steps will mean if pot value reads 20, motors will run for 20/5 * 50ms = 200ms. Increasing this value will mean less length for the same pot reading, and vice versa for decreasing.

then you do

  int potVal = analogRead(A3);
  potVal = potVal / stepsPer;
  potVal = potVal + 10;

➜ that's a lot of "magic" numbers there... make sure you double check the assumptions and how potVal is further used to make decisions

Thank you Jackson

The pot is used as a 0-5v I do know that fact at least but his code has thrown me completely as it’s not a easy read

Like I said the program works but it’s a mess and unsure what he was thinking as some of it is relevant but other bit look like a program that has been adapted

Kindest regards

Simon

if you don't count the comments and empty lines, the code is probably less than 200 lines long (not counting the #define)

If I were facing this, I would just throw the code away and start from scratch...

1 Like

if you look at the function, everything is correct, the driver works when the device selection signal is high

// ---------------------------------------------------------------
// Write to the DRV
// ---------------------------------------------------------------
void DRV_Write ( byte reg, uint16_t newValue )
{
  uint8_t tempOut;
  SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
  // take the SS pin high to select the chip:
  digitalWrite(DRV_SPI_CS_PIN, HIGH);
  // We dont want the top four bits, DRV registers are 12bit
  newValue = newValue & 0x0FFF;
  // Send the DRV the address and value via SPI:
  tempOut = ( (reg << 4) | DRV_WRITE_MASK );
  tempOut = tempOut | (uint8_t)(( newValue >> 8 ) & 0x000F);
  SPI.transfer( tempOut );
  tempOut = (uint8_t)( newValue & 0x00FF);
  SPI.transfer( newValue );
  // take the SS pin low to de-select the chip:
  digitalWrite(DRV_SPI_CS_PIN, LOW);
  SPI.endTransaction();
}

Working with the driver is not done according to Feng Shui based on the datasheet - The serial data consists of a 16-bit serial write, with a read/write bit, 3 address bits and 12 data bits. SPI.transfer16(transmission); would be more appropriate

Did you try doubling, and then halving, that constant to see what it's effect might be, given that you want to change the length by a factor of two?

First, post the code that you are actually using.
The code you posted does not even compile.

Apparently I forgot the library in the library)))

No, actually you futzed the code copy from the IDE.

  1. in the IDE, with your code loaded, press ctrl-T to format the code for viewing.
  2. press ctrl-shift-C to copy the code properly encapsulated for the forum
  3. in your posting, simply press ctrl-V. That's it. it is that simple. You get the whole Content, and nothing but the content.

Hi Camsysca

No Not yet will try Monday when I'm back in work and let you know

simon

Hi Jackson
I do agree with you completely my issue is time I plan to write a new program before launch also I need to design a new board as A4 and A5 have been used so to get past this he also introduced a second nano to run the display
It’s been a uphill battle but if I can get to the the second prototype milestone with length fixed and the start button fault that only happens if there is a paper break
Then I will have 2 months to fix all the issues and write a new program

Thanks again for all your support it’s very much appreciated