Art Controller Adjustments

Home Evil Mad Scientist Forums Other kit and product support Art Controller Adjustments

This topic contains 15 replies, has 2 voices, and was last updated by  bafaction 3 months, 3 weeks ago.

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
    Posts
  • #27219

    bafaction
    Participant

    I have not doing any programming and was wondering if anyone can help
    Me with a little bit of reprogramming for the art controller

    I 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

    #27220

    Windell Oskay
    Keymaster

    We can help with alternate programs, but you’ll need to be explicitly clear about exactly what it is that you want it to do.

    #27224

    bafaction
    Participant

    I 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/12

    the Art Controller relay board
    Release version 1.0

    Product info:
    http://evilmadscience.com/productsmenu/tinykitlist/580

    Documentation:
    http://wiki.evilmadscience.com/Art_Controller

    Target: 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 install

    A 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 verified

    avrdude: safemode: lfuse reads as 64
    avrdude: safemode: hfuse reads as DB
    avrdude: safemode: efuse reads as FF
    avrdude: safemode: Fuses OK

    avrdude 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 maximum

    WDTCSR = 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 8

    asm(“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;
    }
    }

    }

    #27226

    Windell Oskay
    Keymaster

    Did you make these code changes yourself?

    #27230

    bafaction
    Participant

    The 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.

    #27232

    Windell Oskay
    Keymaster

    Ah, that’s here:

    Art Controller Programming

    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?

    #27241

    bafaction
    Participant

    Windell 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

    #27242

    Windell Oskay
    Keymaster

    Can 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.

    #27248

    bafaction
    Participant

    Hope I can make sense with this.

    Par Time = Run time
    Delay Time = Amount of time before the Par Time/Run Time starts

    Let 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 secs

    Below 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 4 months ago by  bafaction.
    #27250

    Windell Oskay
    Keymaster

    I’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.

    #27252

    bafaction
    Participant

    (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.

    #27253

    Windell Oskay
    Keymaster

    It 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?

    #27256

    bafaction
    Participant

    Yes perfect. It should work fine like
    That

    Please make time C and E 0.3 seconds

    Thanks heaps.

    #27264

    Windell Oskay
    Keymaster
    #27338

    bafaction
    Participant

    Thanks 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

Viewing 15 posts - 1 through 15 (of 16 total)

You must be logged in to reply to this topic.