Hello,
Some years ago I made a basic AVR program for a friend for his brake-press in his workshop.
It is written in Basic using Bascom AVR, and we would like to convert it to use the Arduino IDE and also make a modification.
The AVR is a 644P on a custom veraboard circuitboard, which takes a quadrature input from an encoder, and has a couple of inputs, and outputs pulses which drives 2 stepper motor drivers.
The purpose of the project is to adjust the stops of the brake press, so when the hydraulic press is lowered, it lowers to the stop - rather than adjusting the hydraulics to lower to a level.
It is very accurate and my mate is very happy with it, and it has been running for a few years.
The encoder is attached to a hand wheel crank, and from memory is a 250 pulses per revolution encoder, quadrature output.
The output pulses drive 2 stepper motor drivers, which drive 2 stepper motors and move the stop.
There are inputs to select the ratio, ie 1:1, 1:5 or 1:10, so 1 input pulse makes 1 output pulse, or 5 input pulses makes 1 output pulse, or 10 input pulses makes 1 output pulse.
What he is wanting is instead of a reduction, he wants an option for multiplication. So 1 input pulse makes 5 output pulses for example. He said its currently a bit slow and takes a while to move the stop, and would ideally like a faster ratio.
I cant see how to do this though, other than telling him to get hold of a higher pulse count encoder. Getting it to output more pulses than it is receiving, before it gets the next input pulse...
Does anyone have any ideas?
Also is someone able to help port this code. There is nothing complex about it however I am not fully up to the play with the Arduino language yet, that is this weekends mission. It currently runs on 8mhz, but I have a 16mhz crystal on there already but we didnt end up using it for some reason, so its just using the internal oscillator at the moment.
Mainly though I am wanting assistance to ideas for changing the ratio.
Kind Regards
J
Bascom AVR Code to follow (appoligies if its written poorly):
'==============================================================================
' Project: Quadrature input with pulse + direction ouput
' By: JADB
' Description:
' It is controlled by an Atmel ATmega644P 8bit micro controller.
' Quadrature input with pulse + direction ouput, with limit switch cut off
' and limit switch outputs for LED's or PIZO. Pulse output scalable from 1:1,
' 1:5 or 1:10 based on selector switch position.
'==============================================================================
'=====[ Compiler Directives ]==================================================
$crystal = 8000000 ' set via fuse bits to internal RC at 8megs
$regfile = "m644Pdef.dat"
$hwstack = 256
$swstack = 256
$framesize = 256
'------------------------------------------------------------------------------
'=====[ Global Vars ]==========================================================
Dim Lastdirection As Bit ' Stores last direction, 0 or 1.
Dim Countvalue As Integer ' Stores the number of pulses
Dim Q_newvalue(2) As Byte ' Used in Quadrature ISR
Dim Q_oldvalue(2) As Byte ' Used in Quadrature ISR
Dim Q_direction(2) As Byte ' Used in Quadrature ISR
'=====[ Set IO Pins ]==========================================================
''' set data direction registors for io pins
Ddra = &B00000000
'0 & 1 & 2 Limit inputs, bits 6 & 7 are for quadrature input ticks
Ddrb = &B00000000
' bits 0 to 7 not used
Ddrc = &B11111111
' bits 0 output for direction, bit 1 output for pulses, bits 2 & 3 & 4 Limit Indicator Ouputs
Ddrd = &B00000000
' bits 3,5,7 used for Selector Switch,
Switch1_input Alias Pind.3
Switch2_input Alias Pind.5
Switch3_input Alias Pind.7
Direction_output Alias Portc.0
Pulse_output Alias Portc.1
Limit1_output Alias Portc.2
Limit2_output Alias Portc.3
Limit3_output Alias Portc.4
Quada_input Alias Pina.6
Quadb_input Alias Pina.7
Limit1_input Alias Pina.0
Limit2_input Alias Pina.1
Limit3_input Alias Pina.2
'------------------------------------------------------------------------------
'=====[ Enable Pin change interrupt ]==========================================
' The Pin Change Interupts are used for the quadrature imputs.
Pcmsk0 = &B11000000 ' Set mask for pcint0 (PortA.6&7)
Pcicr.0 = 1 ' Enable Pcint0 (Pin Change Interrupt)
On Pcint0 Quad_count_isr ' Set interrupt vector for PCINT0
Pcmsk3 = &B10101000 ' Set mask for pcint3 (PortD.3&5&7)
Pcicr.3 = 1 ' Enable Pcint3 (Pin Change Interrupt)
On Pcint3 Switch_change_isr ' Set interrupt vector for PCINT3
On Compare1a Output_pulse_isr ' Set interrupt vector for Timer1 Compare1a
'------------------------------------------------------------------------------
'=====[ Config misc stuff ]====================================================
Config Timer1 = Timer , Prescale = 1 'Clear Timer = 1
Stop Timer1
Timer1 = 0
Compare1a = 32 '16 = 250kHz, ie 4uS pulse
Enable Timer1
Enable Compare1a
Enable Interrupts
Countvalue = 0
'------------------------------------------------------------------------------
'******************************************************************************
'*****[ Start of main loop ]***************************************************
'******************************************************************************
Do
'Checks which selector switch is on and if the counter has reached the SP
If Switch3_input = 0 And Countvalue >= 40 Then
Countvalue = 0
Set Pulse_output
Timer1 = 0
Start Timer1
Elseif Switch2_input = 0 And Countvalue >= 20 Then
Countvalue = 0
Set Pulse_output
Timer1 = 0
Start Timer1
Elseif Switch1_input = 0 And Countvalue >= 4 Then
Countvalue = 0
Set Pulse_output
Timer1 = 0
Start Timer1
End If
If Limit1_input = 1 Then
Limit1_output = 0
Else
Limit1_output = 1
End If
If Limit2_input = 1 Then
Limit2_output = 0
Else
Limit2_output = 1
End If
If Limit3_input = 1 Then
Limit3_output = 0
Else
Limit3_output = 1
End If
Loop
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
'=====[ Quadrature ISR routine ]============================================
Quad_count_isr:
Q_newvalue(2) = Pina 'copies value of entire port D
Q_direction(2) = Q_oldvalue(2).6 Xor Q_newvalue(2).7 'XOR to get direction of Bits 6 and 7
If Q_direction(2) = 1 Then
Set Direction_output
If Lastdirection = 0 Then 'Handles if the direction is changed, starts conting again
Countvalue = 0 'Write countvalue to 0
Else
If Limit1_input = 1 And Limit2_input = 1 Then 'Ensures it wont move further if a limit is made
Countvalue = Countvalue + 1 'increase the count of countvalue
Else
Countvalue = 0 'stops the counting as the limit has been made
End If
End If
Lastdirection = 1 'sets this as the last direction
Else
Reset Direction_output
If Lastdirection = 1 Then 'Handles if the direction is changed, starts conting again
Countvalue = 0 'write countvalue to 0
Else
If Limit3_input = 1 Then 'Ensures it wont move further if a limit is made
Countvalue = Countvalue + 1 'increase the count of countvalue
Else
Countvalue = 0 'stops the counting as the limit has been made
End If
End If
Lastdirection = 0 'sets this as the last direction
End If
Q_oldvalue(2) = Q_newvalue(2)
Return
'------------------------------------------------------------------------------
'=====[ Switch Change ISR Routine ]============================================
Switch_change_isr:
Countvalue = 0
Lastdirection = 0
Reset Direction_output
Reset Pulse_output
Return
'------------------------------------------------------------------------------
'=====[ Output Pulse period setter ]===========================================
Output_pulse_isr:
Reset Pulse_output
Stop Timer1
Timer1 = 0
Compare1a = 32
Return
'------------------------------------------------------------------------------
End