From 1ce021c76fb9630aae87d560d6c87eb7a6456b76 Mon Sep 17 00:00:00 2001 From: Eduard Iten Date: Mon, 16 Feb 2026 15:49:05 +0100 Subject: [PATCH] Implemented stable IR receiving --- firmware/apps/_samples/ir_recv_sim/src/main.c | 36 +++++++++++++++---- firmware/libs/ir/recv/src/ir_recv.c | 36 ++++++++++++++----- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/firmware/apps/_samples/ir_recv_sim/src/main.c b/firmware/apps/_samples/ir_recv_sim/src/main.c index 9c615ab..bfed647 100644 --- a/firmware/apps/_samples/ir_recv_sim/src/main.c +++ b/firmware/apps/_samples/ir_recv_sim/src/main.c @@ -20,18 +20,40 @@ int main(void) test_packet.data.fields.value = 15; ir_recv_sim_send_packet(&test_packet, NULL); - k_msleep(1000); + k_msleep(500); - LOG_INF("Sending noisy packet with high jitter..."); + LOG_INF("Sending 1. noisy packet with high jitter..."); test_packet.data.fields.id = 255; ir_sim_error_t ext_error = { - .noise_flips_per_8 = 2, /* 2 von 8 Samples pro Block sind falsch */ - .jitter_mark = 2, /* Mark schwankt zwischen 6 und 10 Samples */ - .jitter_space_0 = 4, /* Space0 schwankt zwischen 4 und 12 Samples */ - .jitter_space_1 = 2 /* Space1 schwankt zwischen 14 und 18 Samples */ + .noise_flips_per_8 = 1, /* Maximal 1 Fehl-Sample pro Block (meist im Space) */ + .jitter_mark = 1, /* Mark: 7 bis 9 Samples */ + .jitter_space_0 = 2, /* Space 0: 6 bis 10 Samples */ + .jitter_space_1 = 2 /* Space 1: 14 bis 18 Samples */ }; - ir_recv_sim_send_packet(&test_packet, NULL);//&ext_error); + ir_recv_sim_send_packet(&test_packet, &ext_error); + + k_msleep(500); + + LOG_INF("Sending 2. noisy packet with high jitter..."); + test_packet.data.fields.id = 255; + + ext_error.noise_flips_per_8 = 2; + ext_error.jitter_mark = 1; + ext_error.jitter_space_0 = 2; + ext_error.jitter_space_1 = 2; + ir_recv_sim_send_packet(&test_packet, &ext_error); + + k_msleep(500); + + LOG_INF("Sending 3. noisy packet with high jitter..."); + test_packet.data.fields.id = 255; + + ext_error.noise_flips_per_8 = 1; + ext_error.jitter_mark = 2; + ext_error.jitter_space_0 = 2; + ext_error.jitter_space_1 = 4; + ir_recv_sim_send_packet(&test_packet, &ext_error); return 0; } \ No newline at end of file diff --git a/firmware/libs/ir/recv/src/ir_recv.c b/firmware/libs/ir/recv/src/ir_recv.c index 6f40603..9131be5 100644 --- a/firmware/libs/ir/recv/src/ir_recv.c +++ b/firmware/libs/ir/recv/src/ir_recv.c @@ -147,7 +147,7 @@ void ir_recv_sim_thread(void *p1, void *p2, void *p3) if (sim_sample_pos >= sim_total_samples + 50) { sim_trigger = false; - LOG_INF("Simulation sequence finished."); + LOG_DBG("Simulation sequence finished."); } } } @@ -158,6 +158,7 @@ typedef enum { IR_STATE_IDLE, IR_STATE_HEADER_SYNC, + IR_STATE_WAIT_SPACE, IR_STATE_FIND_MARK, IR_STATE_SYNC_MARK, IR_STATE_VALIDATE @@ -199,13 +200,13 @@ static void process_ir_sample(ir_ctx_t *ctx, int16_t raw) { ctx->state = IR_STATE_HEADER_SYNC; ctx->timer = 0; - LOG_DBG("Header detected. Energy: %u", energy_32); } break; case IR_STATE_HEADER_SYNC: ctx->timer++; - if (energy_8 <= 2) + /* Entspannt: 3 von 8 Samples dürfen verrauscht sein, es gilt trotzdem als Gap */ + if (energy_8 <= 3) { ctx->state = IR_STATE_FIND_MARK; ctx->timer = 0; @@ -215,13 +216,12 @@ static void process_ir_sample(ir_ctx_t *ctx, int16_t raw) else if (ctx->timer > 50) { ctx->state = IR_STATE_IDLE; /* Timeout */ - LOG_DBG("Header sync timeout. Energy: %u", energy_8); } break; case IR_STATE_FIND_MARK: ctx->timer++; - + /* Trigger bei 4 bleibt. Ab 4 Einsen fangen wir an, das Maximum zu suchen */ if (energy_8 >= 4) { ctx->state = IR_STATE_SYNC_MARK; @@ -247,7 +247,8 @@ static void process_ir_sample(ir_ctx_t *ctx, int16_t raw) if (ctx->sync_window >= 10) { - if (ctx->max_energy >= 6) + /* Entspannt: Wenn der Peak mindestens 5 Einsen hat, ist es ein validierter Puls */ + if (ctx->max_energy >= 5) { bool bit = (ctx->timer_at_max >= 20); @@ -262,18 +263,37 @@ static void process_ir_sample(ir_ctx_t *ctx, int16_t raw) } else { - ctx->state = IR_STATE_FIND_MARK; + ctx->state = IR_STATE_WAIT_SPACE; + /* BITWEISER RESYNC: Ja, das funktioniert exakt wie gewünscht. + * Der Timer wird so weit zurückgeschraubt, als ob er GENAU am + * Peak (timer_at_max) auf 0 gesetzt worden wäre. */ ctx->timer = ctx->timer - ctx->timer_at_max; } } else { ctx->state = IR_STATE_IDLE; + LOG_DBG("Mark sync failed. Max Energy: %u", ctx->max_energy); } } break; + case IR_STATE_WAIT_SPACE: + ctx->timer++; + + /* Entspannt: Auch hier lassen wir bis zu 3 Stör-Samples im Space zu */ + if (energy_8 <= 3) + { + ctx->state = IR_STATE_FIND_MARK; + } + else if (ctx->timer > 30) + { + ctx->state = IR_STATE_IDLE; + LOG_DBG("Wait space timeout."); + } + break; + case IR_STATE_VALIDATE: { ir_packet_t p; @@ -283,7 +303,7 @@ static void process_ir_sample(ir_ctx_t *ctx, int16_t raw) if (lastertag_crc8(p.data.bytes, 2) == p.data.fields.crc) { - LOG_INF("VALID: Type %u, ID %u, Val %u", + LOG_DBG(FORMAT_BLUE_BOLD("VALID: Type %u, ID %u, Val %u"), p.data.fields.type, p.data.fields.id, p.data.fields.value);