Need help modifying code

I have the an SMT feeder I made. Attached is the slave code. There is also a master code. I am trying to add two buttons (FORWARD/REVERSE) to make the sprocket go forward and back. The buttons I am using are momentary switches.

I would like it so that when you press the button and it connects the Attiny84 pin to GND, it moves the sprocket by 1 encoder click in the direction of the button. However, if you press and hold the button for X milliseconds, the sprocket would keep turning ignoring the encoder until you let go of the button and then it will stop the motor at the next available encoder point.

Could someone help guide me on how to do this? I need a step by step tutorial. Or if there's already sample code out there I can add to this, please let me know. Thanks!

#define __AVR_ATtiny84__

#include <Arduino.h>

#if defined(__AVR_ATtiny841__)
#define F_CPU 16000000                          // clock speed: 16MHz (external crystal)
#include "WireS.h"                              // I2C library for ATtiny841 (and other modern ATtinys)
#else
#define F_CPU 20000000                          // clock speed: 20MHz (external crystal)
#include "TinyWireS.h"                          // I2C library for ATtiny84A (and other older ATtinys)
#endif

#include <DRV8833.h>

DRV8833 driver = DRV8833();

#define Addr 1

int EncoderCounts = 5;

#define inputA1 PA0
#define inputA2 PA1
#define Sensor1 PA5
#define Sensor2 PA7

#define motorSpeed 255

int start = 0;
int counter = 0;
int MotorDistance;
int direction = 1;  //1 -> forward nd 0-> reverse
int cDir = 0;

String data = "";

void setup() {
   TinyWireS.begin(Addr);
   TinyWireS.onReceive(receiveEvent);    //register a function to be called when slave receive a transmission from master//
   TinyWireS.onRequest(requestEvent);   //register a function when master request data from this slave device
  driver.attachMotorA(inputA1, inputA2);
}

void loop() {
  readInput();
  controlMotors();
}

void readInput() {
  int value1 , value2;
  
  value1 = digitalRead(Sensor1);
  value2 = digitalRead(Sensor2);

  if (start == 1 && value1 == 0) {
    counter += 1;
  }

  if (value1 == 0 && value2 == 1) {
    cDir = 0;
  }
  else
    cDir = 1;

}

void controlMotors() {
  if (counter < MotorDistance * EncoderCounts && start == 1) {
    if (direction == 1) driver.motorAForward(motorSpeed);
    else driver.motorAReverse(motorSpeed);
  }
  else if (counter >= MotorDistance * EncoderCounts && start == 1) {
    driver.motorAStop();
    start = 0;
  }
}

//when slave receive string from master, trigger this event.
void receiveEvent(int howMany)
{
  data = "";
  while (  TinyWireS.available())  // execute repeatedly until last byte left in the data packet from master//
  {
    char c = TinyWireS.read();    // receive data from master and assign it to char c
    data = data + String(c);
  }

  MotorDistance = data.substring(0, data.indexOf(',')).toInt();
  direction = data.substring(data.indexOf(',') + 1 , data.length() + 1).toInt();

  startMotor();
}

void startMotor() {
  for (int i = 0 ; i < 255 ; i++) {
    if (direction == 1) driver.motorAForward(i);
    else driver.motorAReverse(i);
    delay(5);
  }
}

//trigger this event when master request data from slave,
void requestEvent()
{

}

Anyone please?

What is an SMT feeder?

Is the problem in the master or the slave? Posting both programs is usually a good idea.

What does the program you have posted actually do when you run it?

...R

There is no problem. Please read my first post again. I am trying to add a feature. It doesn't matter what the program does currently but I'll clarify - it advances a motor forward based on encoder counts using DRV8833 driver chip. I intentionally left out the master code because it is irrelevant and will only confuse people.The slave receives a command from master to move motor x encoder clicks. And there are many identical slaves.

I'm simply trying to add two momentary switch buttons that when pressed, will tell the DRV8833 to move the motor forward or back for 1 encoder count. If they are pressed for more than X milliseconds, it just keeps driving the motor in that direction until you let go of the button and then ends it on an encoder pulse so that the motor always ends its run on an encoder pulse rather than between.

So, how can I go about adding this feature?

Study the ‘Change State Detection’ example in the IDE.

Hi,

I'm simply trying to add two momentary switch buttons that when pressed, will tell the DRV8833 to move the motor forward or back for 1 encoder count. If they are pressed for more than X milliseconds, it just keeps driving the motor in that direction until you let go of the button and then ends it on an encoder pulse so that the motor always ends its run on an encoder pulse rather than between.

What you are describing is what are called "jog" buttons.

Tom... :slight_smile:

TomGeorge:
Hi,
What you are describing is what are called "jog" buttons.

Tom... :slight_smile:

Yes, I just thought I'd spell it out. Any suggestions on existing code that does this?

shai:
I'm simply trying to add two momentary switch buttons

Are you adding the buttons to the master or the slave?

...R

Have you had any problems with the slave behaving erratically after a certain time, needing a restart?
You are using the String class, example :
data = data + String(c) ;
but without reserving any space for it. This could cause heap storage fragmentation especially with a micro controller with only 8k of ram.