R. Scott Coppersmith
Published © GPL3+

MiniZed and Bob the Blue Element14 Robot Dude

Based on Adam Taylor's - Mini But Mighty, the MiniZed and Vitis for motor control, Bob the Blue Robot Dude dances to MiniZed control.

IntermediateFull instructions provided3 hours861
MiniZed and Bob the Blue Element14 Robot Dude

Things used in this project

Hardware components

MiniZed
Avnet MiniZed
×1
Pmod HB3
Digilent Pmod HB3
×1
element14 blue robot
×1

Story

Read more

Custom parts and enclosures

MiniZed enclosure top

MiniZed enclosure top

MiniZed enclosure bottom

MiniZed enclosure bottom

Code

MiniZed and Mecha-Bob

C/C++
MiniZed Motor Control Application
//Modified by RSC 2/2/2020
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xgpiops.h"
#include "sleep.h"
#include "xil_exception.h"
#include "xttcps.h"
#include "xscugic.h"
#define GPIO_DEVICE_ID  	XPAR_XGPIOPS_0_DEVICE_ID
#define INTC_DEVICE_ID		XPAR_SCUGIC_0_DEVICE_ID
#define	TICK_TIMER_FREQ_HZ	100
#define TTC_TICK_DEVICE_ID	XPAR_XTTCPS_0_DEVICE_ID
#define TTC_TICK_INTR_ID	XPAR_XTTCPS_0_INTR
int direction=1; //motor direction CW or CCW
int speed=0;
static void TickHandler(void *CallBackRef);
int SetupTicker(XTtcPs *TtcPsInst,u16 DeviceID,u16 TtcTickIntrID,XScuGic *InterruptController);
static int SetupInterruptSystem(u16 IntcDeviceID,XScuGic *IntcInstancePtr);
int SetupTimer(u16 DeviceID,XTtcPs *TtcPsInst);
void set_pwm(u32 cycle);
void display_menu();
typedef struct {
u32 OutputHz;	/* Output frequency */
XInterval Interval;	/* Interval value */
u8 Prescaler;	/* Prescaler value */
u16 Options;	/* Option settings */
} TmrCntrSetup;
XGpioPs Gpio;
XGpioPs_Config *ConfigPtr;
XTtcPs_Config *TtcConfig;
XTtcPs ttcTimer;
TmrCntrSetup *TimerSetup;
XScuGic InterruptController;  	/* Interrupt controller instance */
XTtcPs TtcPsInst;
u32 MatchValue;
static TmrCntrSetup SettingsTable={TICK_TIMER_FREQ_HZ, 0, 0, 0};
int main()
{
u8 DutyCycle;
char key_input;
init_platform();
TmrCntrSetup SettingsTable= {TICK_TIMER_FREQ_HZ, 0, 0, 0};
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
XGpioPs_CfgInitialize(&Gpio, ConfigPtr,ConfigPtr->BaseAddr);
XGpioPs_SetDirectionPin(&Gpio, 54, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 54, 1);
XGpioPs_WritePin(&Gpio, 54, direction);
printf("www.adiuvoengineering.com\n\r");
printf("DC Motor Control Example\n\r");
SetupInterruptSystem(INTC_DEVICE_ID, &InterruptController);
SetupTicker(&ttcTimer,TTC_TICK_DEVICE_ID,TTC_TICK_INTR_ID,&InterruptController);
while(1){
  display_menu();
  if (direction==1)
    printf("Direction = CW\n");
  else if (direction==0)
    printf("Direction = CCW\n");
  printf("Speed = %d%%\n",speed);
  read(1, (char*)&key_input, 1);
  switch (key_input) {
    case '0': // toggle direction
      set_pwm(0);
      speed=0;
      if (direction==0x1)
        direction=0;
      else
        direction=1;
      XGpioPs_WritePin(&Gpio, 54, direction);
      break;
    case '1': //stop
      set_pwm(0);
      break;
    case '2': //5%
      DutyCycle = 5;
      set_pwm(DutyCycle);
      speed=DutyCycle;
      break;
    case '3': //10%
      DutyCycle = 10;
      set_pwm(DutyCycle);
      speed=DutyCycle;
      break;
    case '4': //15%
      DutyCycle = 15;
      set_pwm(DutyCycle);
      speed=DutyCycle;
      break;
    case '5': //20%
      DutyCycle = 20;
      set_pwm(DutyCycle);
      speed=DutyCycle;
      break;
    case '6': //25%
      DutyCycle = 25;
      set_pwm(DutyCycle);
      speed=DutyCycle;
      break;
    case '7': //30%
      DutyCycle = 30;
      set_pwm(DutyCycle);
      speed=DutyCycle;
      break;
    }
  }
  cleanup_platform();
  return 0;
  }
void display_menu()
{
//Clear the screen
printf("\033[2J");
//Display the main menu
printf("*******************************************\n");
printf("****      www.adiuvoengineering.com    ****\n");
printf("****      Motor Control Example        ****\n");
printf("****      Modified for Mecha-Bob       ****\n");
printf("****      by RSC 2/2/2020              ****\n");
printf("*******************************************\n");
printf("\n");
printf("   MM10 Motor Control   \n");
printf("------------------------------------------\n");
printf("\n");
printf("Select a Speed:\n");
printf("  (0)   - Toggle Direction\n");
printf("  (1)   - Stop\n");
printf("  (2)   - 5%%\n");
printf("  (3)   - 10%%\n");
printf("  (4)   - 15%%\n");
printf("  (5)   - 20%%\n");
printf("  (6)   - 25%%\n");
printf("  (7)   - 30%%\n");
printf("\n");
}
void set_pwm(u32 cycle)
{
u32 MatchValue;
MatchValue = (TimerSetup->Interval * cycle) / 100;
XTtcPs_SetMatchValue(&ttcTimer, 0, MatchValue);
}
int SetupTicker(XTtcPs *TtcPsInst,u16 DeviceID,u16 TtcTickIntrID,XScuGic *InterruptController)
{
int Status;
TmrCntrSetup *TimerSetup;
XTtcPs *TtcPsTick;
TimerSetup = &SettingsTable;
TimerSetup->Options |= (XTTCPS_OPTION_INTERVAL_MODE |
XTTCPS_OPTION_MATCH_MODE | XTTCPS_OPTION_WAVE_POLARITY);
Status = SetupTimer(DeviceID,TtcPsInst);
if(Status != XST_SUCCESS) {
return Status;
}
TtcPsTick = TtcPsInst;
Status = XScuGic_Connect(InterruptController, TtcTickIntrID,
(Xil_InterruptHandler)TickHandler, (void *)TtcPsTick);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XScuGic_Enable(InterruptController, TtcTickIntrID);
XTtcPs_EnableInterrupts(TtcPsTick, XTTCPS_IXR_INTERVAL_MASK);
XTtcPs_Start(TtcPsTick);
return Status;
}
static int SetupInterruptSystem(u16 IntcDeviceID,XScuGic *IntcInstancePtr)
{
int Status;
XScuGic_Config *IntcConfig;
IntcConfig = XScuGic_LookupConfig(IntcDeviceID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler,
IntcInstancePtr);
Xil_ExceptionEnable();
return XST_SUCCESS;
}
int SetupTimer(u16 DeviceID,XTtcPs *TtcPsInst)
{
int Status;
XTtcPs_Config *Config;
XTtcPs *Timer;
TmrCntrSetup *TimerSetup;
TimerSetup = &SettingsTable;
Timer = TtcPsInst;
Config = XTtcPs_LookupConfig(DeviceID);
if (NULL == Config) {
return XST_FAILURE;
}
Status = XTtcPs_CfgInitialize(Timer, Config, Config->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XTtcPs_SetOptions(Timer, TimerSetup->Options);
XTtcPs_CalcIntervalFromFreq(Timer, TimerSetup->OutputHz,
&(TimerSetup->Interval), &(TimerSetup->Prescaler));
XTtcPs_SetInterval(Timer, TimerSetup->Interval);
XTtcPs_SetPrescaler(Timer, TimerSetup->Prescaler);
return XST_SUCCESS;
}
static void TickHandler(void *CallBackRef)
{
u32 StatusEvent;
/*
* Read the interrupt status, then write it back to clear the interrupt.
*/
StatusEvent = XTtcPs_GetInterruptStatus((XTtcPs *)CallBackRef);
XTtcPs_ClearInterruptStatus((XTtcPs *)CallBackRef, StatusEvent);
//printf("timer\n\r");
/*update the flag if interrupt has been occurred*/
//UpdateFlag = TRUE;
}

Credits

R. Scott Coppersmith

R. Scott Coppersmith

15 projects • 24 followers
Research Engineer, Embedded systems designer
Thanks to Adam Taylor.

Comments