So I am designing a wired fencing scoring system. There already exists an arduino based analog wired scoring system, however the analog system has a few fundamental problems.
A quick explanation of fencing scoring machines. There are three different weapons; however, I will only talk about foil since that addresses the difficult problems that if solved then also solve the other weapons.
In foil there are two fencers with three wires that go into the box for each fencer. I will call the three wires line A, line B and line C. Line A is connected to the fencers lame (a metalic vest which is considered valid target area). Line B is connected to a wire that goes to the end of the weapon and into a button. Line C is connected to the weapon's blade.
If line B and line C complete a circuit then the button is not depressed. Once line B and C break (open circuit) then the button is pressed. The end of the button is insulated from line C and is only connected to line B. If the button touches the opponent then line B will complete a circuit with line C of the opponent (that is considered a valid touch).
So I want to make this system of detecting if the lame is touched a digital and not analog, because in an analog system there is no way of distinguishing which fencer the incoming voltage to line C is coming from. The only solution is to send different voltages, however those voltages can change with different resistance values of the fencers blade and body cord which is not a controlled variable.
I found a solution to this problem in a digital system.
If I send two different PWM signals from the two different fencers I just have to read the PWM signal touching the lame. I know if the button is pressed or not, and if the button is pressed on the first fencer and the first fencers PWM signal is going into the lame of the second fencer or if a combination of those two are coming into the second fencers lame then it is a valid touch.
I've attached a picture of what the two signals would need to be and what the combination would look like. The two signals need to synchronized, which shouldn't be hard if I use the same timer to generate the signals. The arduino nano (which is what I am using shares pin 9 and 10 on the same timer).
My question is how would I tell the arduino to generate those two signals?
The only way I know how to create a PWM signal is using analogWrite(). Which from my understanding specifies the duty cycle.
Can anyone help?
EDIT: It wouldn't let me upload the image as an attachment, so here is a link to it on imgur
if you were not to used analogWrite() what frequency would you be PWM'ing?
coz it can be done without using analogWrite() assuming the intended output frequency allows it...
void setup()
{
pinMode(ledPin, OUTPUT);
// initialize timer1
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 31250; // compare match register 16MHz/256/2Hz
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts
}
ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine
{
static int x;
digitalWrite(x == 1);
digitalWrite(x >= 3);
x++;
if (x == 5) x = 0;
}
void loop()
{
// your program here...
}
this creates a pulse on digital pins 12 and 13
this should generate your pulse sequence at a slow 2 Hz per step with 5 steps per cycle
16,000,000 / 256 / 2hz = 13250
change this number to increase/decrease the frequency
z
I don't see why you need PWM signals for this. Your diagram just shows a simple square wave and that can be generated with digitalWrite() or use the digitalWriteFast library if the extra performance is needed.
Use micros() to manage the timing and then any phase relationship you want is easy to achieve.
...R
zhomeslice:
this creates a pulse on digital pins 12 and 13
this should generate your pulse sequence at a slow 2 Hz per step with 5 steps per cycle
16,000,000 / 256 / 2hz = 13250
change this number to increase/decrease the frequency
I like that this doesn't use the program loop but the timers instead. However I am having a hard time understanding what the code is doing exactly. How do you specify pin 12 and 13? I noticed that you are only doing digitalWrite(x==1) etc, shouldn't digital write take two parameters?
Also since I need this to run in as high of a frequency as I can possibly achieve I was trying to understand what you meant changing the number. you write
16,000,000 / 256 / 2hz = 13250
however I don't see any number having this resembles in the code.
Also I see that you've disabled all interrupts before you set up the timer then enabled them. Could you explain the reasoning behind that a bit? Thank you very much.
yoseph1998:
I like that this doesn't use the program loop but the timers instead. However I am having a hard time understanding what the code is doing exactly. How do you specify pin 12 and 13? I noticed that you are only doing digitalWrite(x==1) etc, shouldn't digital write take two parameters?
Take a look at section 18. I/O-Ports and 20. 16-bit Timer/Counter1 (TC1) with PWM in the datasheet of the Atmega326P. Section 18 shows how can you configure your pins.
So pin 12 and 13 as output, using https://www.elecrom.com/wp-content/uploads/2017/01/arduino-uno-pinout-pin-mapping.jpg
uint8_t p12 = 4; //pin 12 = PB4
uint8_t p13 = 5; //pin 13 = PB5
DDRB |= (1 << p12) | (1 << p13); // set pins as output, write 1 to their description register
// zero is input.
//writing to the pins
PINB |= (1 << p12); // toggling pin 12
PORTB |= (1 << p13); // setting pin 13
PORTB &= ~(1 << p13); // clearing pin 13
yoseph1998:
Also since I need this to run in as high of a frequency as I can possibly achieve I was trying to understand what you meant changing the number. you write however I don't see any number having this resembles in the code.
Also I see that you've disabled all interrupts before you set up the timer then enabled them. Could you explain the reasoning behind that a bit? Thank you very much.
Section 20 shows you how you can configure your timer. The code of zhomeslic shows how it's done with commentary.
256 is encoded in the CS1x bits, this sets the prescaler of the timer, so that the timer counts at a speed of 16MHz / 256 = 62.5 kHz. To generate the correct frequency you need to load a compare value in the OCR1x register.
So
f_clk = 16e6
f = desired frequency
OCR1A = f_clk / (f * prescale) - 1