Skip to main content
Graduate II
November 11, 2024
Question

Scan inputs and drive outputs after delay

  • November 11, 2024
  • 6 replies
  • 4210 views

Delete

    This topic has been closed for replies.

    6 replies

    Super User
    November 11, 2024

    Why do you have three separate timers?

    Surely you just need one timer to give you a "tick", and then you do all your sampling and updating on each tick?

     


    @XooM wrote:

    I have 8 outputs. I read (sic?) them ...


    You mean write them?

    XooMAuthor
    Graduate II
    November 11, 2024

    I don't know. I think I'm doing something wrong.

    I use 1 timer to scan 24 LEDs with 2 74hc595.
    * When some inputs come, I activate the relevant output.

    For example, if (input 1 + input 2 + input 5) comes, I activate the Q1 output.

    Super User
    November 11, 2024

    @XooM wrote:

    For example, if (input 1 + input 2 + input 5) comes, I activate the Q1 output.


    You didn't mention anything about performing logic on the inputs before driving the outputs.

    I suggest that you forget about that to start with, and just get the delay working.

    I would suggest using a 500-entry circular buffer. Each millisecond:

    1. Read the inputs
    2. Drive the LEDs for the inputs
    3. write the input data to the start of the buffer;
    4. Read the end of the buffer
    5. write that data to the outputs, and associated LEDs.

    For testing, use a much shorter ring buffer - then you can easily see the data "walking" through it...

     

    https://en.wikipedia.org/wiki/Circular_buffer

    Technical Moderator
    November 11, 2024

    Hello,

    I suggest you to test your code in a real HW not in simulation with like Proteus/Labcenter. 

    If needed contact them: https://www.labcenter.com/

    XooMAuthor
    Graduate II
    November 11, 2024

    I'm working on a real circuit.

    Technical Moderator
    November 11, 2024

    What STM32 are you using? What board are you using? ST? Custom board?

    Technical Moderator
    November 11, 2024

    As you are not using a real HW, the thread has been moved to Other/Software board.

    Explorer
    November 11, 2024

    I don't quite understand.
    > I have 8 outputs. I read them with timer17 at 1ms intervals.

    Do you want to read back the output values ?
    The schematics is too small to decipher any IC types, This outputs seem to be connected said 8-bit shift register. But as said, I can see if as inputs or outputs.

    > I have 14 inputs. I read the inputs with timer2 at 1ms intervals to see if there are any inputs.
    > I have 8 outputs. I read them with timer17 at 1ms intervals.

    Why not read all at once, in the same routine ?
    I would use a SysTick interrupt for that, configured to 1ms.

    And if you need to care about timing and consistency, add latches to the input.
    Otherwise inputs might change in the middle of the read-out process.

    > I need a 500ms time delay in such a system, but unfortunately I cannot create this delay and my whole system is blocked. When I set and use a 500ms time interrupt with timer15, the system is blocked.

    Sounds like you want to wait inside a (500ms) timer interrupt handler routine for that timeout.
    This is a bad idea, as it blocks other interrupts.

    This can be done by counter values (variables) from within the SysTick interrupt as well.
    Define a global (volatile) variable, and decrement it by 1 in the SysTick handler when not zero.
    When the variable is back to zero, the timeout has expired.

    XooMAuthor
    Graduate II
    November 11, 2024

    I control a total of 24 LEDs on 8 outputs, 3 of which are connected to 1 74hc4094 output.

    I am trying to turn on the LED I want by scanning them with a timer.

    Super User
    November 11, 2024

    Well, that was totally missing from your initial post & schematic!

     

    So, for each 3-bit pattern that you clock into the right-hand shift register on 'x', you have to clock an 8-bit pattern into  the left-hand shift register on 'DATA' ?

     

    What, exactly, are you trying to achieve by that?

    It seems excessively complicated!

     

    Again, I think you need to take just getting the LEDs to work as a project on its own before doing anything else!

     

    Start by drawing a truth table.

    Graduate II
    November 11, 2024

    Make a table of tasks, decrement a count in SysTick_Handler(), and when you hit zero call the action function.

    Set the count to 500 for your delayed execution.

    Or make a table you check in main() loop, where you delta a time stamp off of HAL_GetTick(), and check your trigger point.

    You don't need to block, just be aware of time and when the timeout will expire.

    Need to move beyond linear/sequential code execution and delays

    XooMAuthor
    Graduate II
    November 12, 2024

    This code is blocking my interrupts.

    #define SYSTICK_LOAD (SystemCoreClock/1000000U)
    #define SYSTICK_DELAY_CALIB (SYSTICK_LOAD >> 1)
     
    #define DELAY_US(us) \
     do { \
     uint32_t start = SysTick->VAL; \
     uint32_t ticks = (us * SYSTICK_LOAD)-SYSTICK_DELAY_CALIB; \
     while((start - SysTick->VAL) < ticks); \
     } while (0)
     
    #define DELAY_MS(ms) \
     do { \
     for (uint32_t i = 0; i < ms; ++i) { \
     DELAY_US(1000); \
     } \
     } while (0)
     
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
     
    int main(void)
    {
     HAL_Init();
     SystemClock_Config();
     MX_GPIO_Init();
    Super User
    November 12, 2024

    So don't do that - don't use blocking delays!

    Again, you say this hardware is already being used - so there must already be software to do the basics of scanning the inputs, etc.

    Why don't you just use that?

    XooMAuthor
    Graduate II
    November 12, 2024

    I told you I was using real hardware. You moved the location to the wrong place.