Home › Evil Mad Scientist Forums › Other kit and product support › Art Controller Adjustments
Tagged: good idea
- This topic has 15 replies, 2 voices, and was last updated 5 years, 7 months ago by bafaction.
-
AuthorPosts
-
April 9, 2019 at 7:41 pm #27219bafactionParticipant
I have not doing any programming and was wondering if anyone can help
Me with a little bit of reprogramming for the art controllerI already have been given a code a lot of years ago for a 3 sec delay to the start. What I am asking for now is to use PB3 and another relay signal output but have this ouput turn on for 0.5 sec as time starts and then 0.5sec before the time finishes.
If anyone can help me out that would be great. I don’t even know where to start to change the program
Thanks in advance
April 9, 2019 at 7:58 pm #27220Windell OskayKeymasterWe can help with alternate programs, but you’ll need to be explicitly clear about exactly what it is that you want it to do.
April 9, 2019 at 11:52 pm #27224bafactionParticipantI am using the relay to control a solenoid for a locking mechanism or a target face time for some target shooting events. One of the events requires a start and stop buzzer.
I had the original Art Controller file changed to give me a 3 sec delay when the start button has been pressed before the delay time is active. (Below is a copy of adjusted file) I have set up the delay time adjusts via a rotary binary switch. This allows me to select from 3 seconds up to 15 seconds delay time.
What I am trying to achieve is having another output from the art controller such as i/o PB3 to drive an external relay board which will activate the buzzer, But this relay drive has to be at the start of the delay time and at the end of the delay time and run for about half a second.
I hope this makes sense
/*
Title: artcon.c
Author: Windell H. Oskay
Date Created: 7/16/12
Last Modified: 9/13/12the Art Controller relay board
Release version 1.0Product info:
http://evilmadscience.com/productsmenu/tinykitlist/580Documentation:
http://wiki.evilmadscience.com/Art_ControllerTarget: Atmel ATtiny2313A MCU
Fuse configuration:
Use 8 MHz internal RC oscillator, with divide-by-8 clock prescaler: 1 MHz clock
BOD active at 2.7 V.Fuses: -U lfuse:w:0x64:m -U hfuse:w:0xdb:m -U efuse:w:0xff:m
————————————————-
USAGE: How to compile and installA makefile is provided to compile and install this program using AVR-GCC and avrdude.
To use it, follow these steps:
1. Update the header of the makefile as needed to reflect the type of AVR programmer that you use.
2. Open a terminal window and move into the directory with this file and the makefile.
3. At the terminal enter
make clean <return>
make all <return>
make install <return>
4. Make sure that avrdude does not report any errors. If all goes well, the last few lines output by avrdude
should look something like this:avrdude: verifying …
avrdude: XXXX bytes of flash verifiedavrdude: safemode: lfuse reads as 64
avrdude: safemode: hfuse reads as DB
avrdude: safemode: efuse reads as FF
avrdude: safemode: Fuses OKavrdude done. Thank you.
If you a different programming environment, make sure that you copy over the fuse settings from the makefile.
*/
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*/
#include <avr/io.h> // device specific I/O definitions
#include <avr/interrupt.h>// System clock : 1 MHz
// Set compare to once every 124 cycles– so every 124 microseconds
#define MICROSECONDS_PER_COMPARE 124#define TurnCoilOn(); PORTB |= 16;
#define TurnCoilOff(); PORTB &= 239;// Inputs: PA0, PA1
#define InputMaskA 3// Inputs: PB0 – PB3
#define InputMaskB 15// Inputs: PD0 – PD6
#define InputMaskD 127//volatile variables: ones that may be modified in an ISR
volatile unsigned int timer0_microseconds;
volatile unsigned int timer0_millis;
volatile unsigned long timer0_seconds;// Note: Seconds (timer0_seconds) will not overflow in realistic time periods.
// Maximum unsigned long is 2^32 – 1, or 4 294 967 295
// 4 294 967 295 seconds, or about 136 years.unsigned long millis(void)
{ // Return total milliseconds ***since last timer reset***
// Will roll over after 49 days.unsigned int mills;
unsigned long secs;
uint8_t oldSREG = SREG;// disable interrupts while we read timer values or we might get an
// inconsistent value
cli();
mills = timer0_millis;
secs = timer0_seconds;
SREG = oldSREG;secs = 1000 * secs + mills;
return secs;
}unsigned long seconds(void)
{
unsigned long m;
uint8_t oldSREG = SREG;// disable interrupts while we read timer0_seconds or we might get an
// inconsistent value (e.g. in the middle of a write to timer0_seconds)
cli();
m = timer0_seconds;
SREG = oldSREG;return m;
}void resetTimer(void)
{
uint8_t oldSREG = SREG;
cli();// disable interrupts to avoid possible
// inconsistent values (e.g. in the middle of a write to timer0_millis)timer0_microseconds = 0;
timer0_millis = 0;
timer0_seconds = 0;SREG = oldSREG;
return;
}unsigned long calculateStopTime (void)
{
unsigned long total = 0;
unsigned int temp = 1;if ((PIND & _BV(5)) == 0)
total = 1;
if ((PIND & _BV(4))== 0)
total += 2;
if ((PIND & _BV(3)) == 0)
total += 4;
if ((PIND & _BV(2)) == 0)
total += 8;
if ((PINA & _BV(0)) == 0)
total += 16;if (total == 0)
total = 1;if ((PINA & _BV(1))== 0)
temp *= 6;
if ((PIND & _BV(1))== 0)
temp *= 10;
if ((PIND & _BV(0))== 0)
temp *= 60;return total * temp;
}int main (void)
{
unsigned long StopTime;
unsigned long debounceStartTime;uint8_t Triggered;
uint8_t CoilOn;
uint8_t doCancel;
uint8_t debounced;
uint8_t TrigInLast;
uint8_t TrigIn;DDRA = 0;
DDRB = _BV(4); // Set line B4 to be an output, the rest are inputs.
DDRD = 0;// Pull-ups on inputs:
PORTA = InputMaskA;
PORTB = InputMaskB;
PORTD = InputMaskD;CLKPR = (1 << CLKPCE); // enable clock prescaler update
CLKPR = 0; // set clock to maximumWDTCSR = 0x00; // disable watchdog timer
// Set up the timer interrupt:
TCCR0A = 2;
OCR0A = 128;TIFR = (1 << TOV0); // clear interrupt flag
TIMSK = (1 << OCIE0A); // enable compare interrupt
TCCR0B = (1 << CS01); // start timer, prescale by 8asm(“sei”); // ENABLE global interrupts
uint8_t pinbCopy = PINB;
resetTimer();
StopTime = calculateStopTime();if ((pinbCopy & 1) && ((pinbCopy & 2) == 0)) {
// If Cancel is false (b0 is high) and trigger at reset is true (B1 is low), trigger… Now!
TurnCoilOn();
Triggered = 1;
CoilOn = 1;}
else
{
TurnCoilOff();
Triggered = 0;
CoilOn = 0;
}debounced = 0;
debounceStartTime = 0;TrigInLast = ((PIND & _BV(6)) == 0);
for (;;) { // main loop
TrigIn = ((PIND & _BV(6)) == 0); // 1 if trigger input is asserted (trigger pin is grounded). Zero otherwise.
doCancel = 0;if ( TrigIn && (TrigInLast == 0) && (debounced > 1))
{ // Legitimate button press/input signal detected.// Check for new trigger:
if (Triggered == 0)
{
if (PINB & 1) // Make sure that cancel pin is HIGH (not active):
{
resetTimer();
StopTime = 3;
while ( seconds () < StopTime)
{}
resetTimer();
StopTime = calculateStopTime();
TurnCoilOn();
Triggered = 1;
CoilOn = 1;
}
}
else if ((PINB & _BV(2)) == 0) // If start/stop on trig is selected (low)
{
doCancel = 1;
}
}if ( TrigIn == 0 ){
if (TrigInLast) // Trig in button/signal just released
{
debounceStartTime = millis();
debounced = 1; // Intermediate Step
}
else
{
if ((millis() – debounceStartTime) > 50) // Trigger input released for 50 ms: “released”
{
debounced = 2; // Debouncing routine complete.
}}
}if (TrigIn)
{ //Input is asserted; reset debounce counter.
debounced = 0;
}if (Triggered)
{if ((PINB & _BV(0)) == 0) // If Cancel signal is asserted…
{
doCancel = 1;
}if (seconds() >= StopTime) { // If time has run out
if (PINB & _BV(3))
{ // Repeat mode is off.
doCancel = 1;
}
else
{
// Repeat mode is ON; begin the next part of the cycle.
resetTimer();
StopTime = calculateStopTime();if (CoilOn) {
TurnCoilOff();
CoilOn = 0;
}
else {
TurnCoilOn();
CoilOn = 1;
}
}
}if (doCancel)
{
TurnCoilOff();
Triggered = 0;
CoilOn = 0;
}
}TrigInLast = TrigIn;
} //End main loop
return 0;
}SIGNAL (TIMER0_COMPA_vect) {
timer0_microseconds += MICROSECONDS_PER_COMPARE;
if (timer0_microseconds > 1000) {
timer0_millis++;
timer0_microseconds -= 1000;if (timer0_millis > 1000) {
timer0_seconds++;
timer0_millis -= 1000;
}
}}
April 10, 2019 at 10:57 am #27226Windell OskayKeymasterDid you make these code changes yourself?
April 10, 2019 at 2:13 pm #27230bafactionParticipantThe only part that was changed is below.
if (PINB & 1) // Make sure that cancel pin is HIGH (not active):
{
resetTimer();
StopTime = 3;
while ( seconds() < StopTime)
{}
resetTimer();
StopTime = calculateStopTime();
TurnCoilOn();
Triggered = 1;
CoilOn = 1;
}I was advised by someone on this forum 6 years ago in how to change this.
April 10, 2019 at 7:59 pm #27232Windell OskayKeymasterAh, that’s here:
It’s a bit of a hack– untested, as I said.
The changes that you’re asking for now are a little more invasive, and should be tested.
If I understand correctly, the changes (versus the standard program) that you are asking for are as follows:
(1) Change PB3 from an input to an output.
(2) Add a 3 second delay after receiving a trigger.
(3) After the 3 second delay, turn PB3 high.
(4) After PB3 goes high, add a 0.5 second delay.
(5) After the 0.5 second delay, turn PB3 low.
(6) Start the “real” delay, which is to the programmed input time delay, minus one second.
(7) When the delay time expires, turn PB3 high.
(8) After PB3 goes high, add a 0.5 second delay.
(9) After the 0.5 second delay, turn PB3 low. Then, wait for the next trigger.
Is that all correct?
April 13, 2019 at 3:21 pm #27241bafactionParticipantWindell the 3 sec hack worked. I have been using that for the past 6 years.
1- yes please make it a output
2- 3 Sec Delay works perfectly with the adjusted program
3- Yes at the start of the programed par time
4- Yes for 0.3 – 0.5 sec max
5- Yes
6- No. I would like the PB3 and PB4 to both start at the programmed par time
7- Well Kinda. I would like the the PB3 high 0.2 before PB4 goes low (par time ends) and stay high for a further 0.1 (Total time high 0.3 max 0.5)
8- Yes see my point 7
9- Yes
I hope this now makes more sense.
Appreciate your help
April 14, 2019 at 3:57 pm #27242Windell OskayKeymasterCan you write down what exact sequence of events you want? It seems like there are additional things here that you still have not explained.
I’m not sure what the “par” time is. On numbers 3, 6, and 7, I’m really not sure what it is that you’re asking for.
April 15, 2019 at 3:56 pm #27248bafactionParticipantHope I can make sense with this.
Par Time = Run time
Delay Time = Amount of time before the Par Time/Run Time startsLet go back to the basic program without the 3 second delay.
I set say 5 seconds par/run time using the dip switches.
I activate the trigger input via an external Momentary Push Switch
This then starts the Par time/Run time for PB4 to go high for 5 secsBelow is the sequence of events
1) Activate trigger wait 3 seconds (Delay Time) before starting the Par
time/Run time
2) Once Par Time/Run Time Starts we activate PB4 high and stays high for the
entire Par Time/Run Time
3) Once Par Time/Run Time Starts we activate PB3 High for a total run time of
0.3-0.5 seconds max then PB3 goes low.
4) End of the Par Time/Run Time PB4 goes Low
5) PB3 to go high 0.2 secs before PB4 goes low and stays high for a
further 0.2 – 0.3 seconds then goes low.
6) Wait for Next Trigger to start the sequence again.- This reply was modified 5 years, 8 months ago by bafaction.
April 15, 2019 at 4:49 pm #27250Windell OskayKeymasterI’m still not following.
You are saying that “Par Time = Run time”. Okay.
(A) It also sounds like you are saying that “Par Time = Run time = time set by dip switches” — is that correct?
(B) It also sounds like you are saying that “Par Time = Run time = 0.3-0.5 seconds” — is that correct?
I don’t see how it can be both.
I should also reiterate: Making these changes to the code is straightforward — but I cannot do it if you cannot state clearly _exactly_ what is supposed to happen.
- This reply was modified 5 years, 8 months ago by Windell Oskay.
April 15, 2019 at 6:02 pm #27252bafactionParticipant(A) Yes the par time/run time is what it set by the dip switches
(B) Yes as this is how long I would like the PB3 to run for. It does not have to be adjusted via any external means. If it can be a part of the program only.
Please let me know if you need more information.
April 15, 2019 at 6:30 pm #27253Windell OskayKeymasterIt sounds like you’re saying that (A) was correct, and (B) was not– that is, that this is actually a separate “run time” which is not equal to the setting on the DIP switches.
If I understand what you are saying, there are now a number of separate delay intervals. Let’s give them names so that we can tell them apart:
(A) The post-trigger delay, fixed at 3 seconds. We’ll call this “TIME A” to be clear.
(B) The time delay, set by the DIP switches. We’ll call this “TIME B” to be clear.
(C) A third time delay, called “TIME C”, that is somewhere in the range 0.3 – 0.5 seconds.
(D) A fourth time delay, called “TIME D”, that is 0.2 seconds
(E) A fifth time delay, called “TIME E” that is in the range 0.1 – 0.3 seconds, or perhaps 0.2 – 0.3 seconds.
You have given me several different values for these different time delays. If these values are going to be set in the program only, then you need to pick values for each of these, particularly TIME C and TIME E that still have time ranges.
Let’s see if we have this all together then:
The changes (versus the standard program) that you are asking for are now as follows:
(1) Change PB3 from an input to an output.
(2) Add a time delay (“TIME A”) of 3 seconds after receiving a trigger, without doing anything else.
(3) After that time delay, simultaneously turn on the relay and turn PB3 high. This occurs at “TIME A” after the initial trigger signal.
(4) After some to-be-specified time (“TIME C”), take PB3 low. The time between the initial trigger signal and PB3 going low is “TIME A” + “TIME C”.
(5) At a time of “TIME A” + “TIME B” – “TIME D” from receiving the trigger signal, take PB3 high again. This is an interval “TIME D” before the end of the relay turning off.
(6) At time “TIME A” + “TIME B” (the time delay set by the DIP switches plus three seconds after the initial trigger), turn the relay off.
(7) At time “TIME A” + “TIME B” + “TIME E”, turn PB3 low.
Then, wait for the next trigger.Is this correct?
April 16, 2019 at 12:53 am #27256bafactionParticipantYes perfect. It should work fine like
ThatPlease make time C and E 0.3 seconds
Thanks heaps.
April 18, 2019 at 10:08 am #27264Windell OskayKeymasterHere is a version that you can try:
https://evilmadscientist.s3.amazonaws.com/scratch/artcon.cApril 26, 2019 at 2:51 pm #27338bafactionParticipantThanks Heaps. I will Be testing the code this weekend. I had to wait to gain access to the art controller.
I will let you know how it goes.
Thanks heaps
-
AuthorPosts
- You must be logged in to reply to this topic.