Browse Source

Add initial interrupt reading

- Start reading pin values on interrupts to determine the on time
- Store the on times in `channelVals`
- Print them out if `INT_MODE` is set

Next step is to rework the existing control code to read from these
values, rather than using `pulseIn()`.
Jason Tarka 4 years ago
parent
commit
2f85ab436e
4 changed files with 50 additions and 3 deletions
  1. 18 1
      01_setup.ino
  2. 20 0
      02_readPins.ino
  3. 9 1
      03_main.ino
  4. 3 1
      rc_receiver_driving.ino

+ 18 - 1
01_setup.ino

@@ -1,6 +1,6 @@
 
 void setup() {
-	Serial.begin(9600);
+	Serial.begin(115200);
 
 	pinMode(LEFT_MOTOR_PIN, OUTPUT);
 	pinMode(RIGHT_MOTOR_PIN, OUTPUT);
@@ -11,5 +11,22 @@ void setup() {
 		pinMode(channels[i], INPUT);
 	}
 
+	enableInterrupts();
+
 	delay(2000);
 }
+
+void enableInterrupts() {
+	for(byte i = 0; i <= NUM_CHANNELS; i++) {
+		byte pin = channels[i];
+		
+		*digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin));  // enable pin
+		PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
+		PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group 
+	}
+}
+
+// handle pin change interrupt for D8 to D13 here
+ISR (PCINT0_vect) {
+	readPins();
+}

+ 20 - 0
02_readPins.ino

@@ -0,0 +1,20 @@
+unsigned long highStartTimes[NUM_CHANNELS + 1];
+
+void readPins() {
+	const unsigned long now = micros();
+//	Serial.print("Interrupt started: ");
+//	Serial.println(now);
+	for(byte ch = 1; ch <= NUM_CHANNELS; ch++) {
+		byte pin = channels[ch];
+		boolean isHigh = digitalRead(pin) == HIGH;
+
+		if(isHigh && highStartTimes[ch] == 0) {
+			// First time seeing this pin go high.
+			highStartTimes[ch] = now;
+		} else if(!isHigh && highStartTimes[ch] != 0) {
+			// Channel was high, now low. Record how long it was high for.
+			channelVals[ch] = now - highStartTimes[ch];
+			highStartTimes[ch] = 0;
+		}
+	}
+}

+ 9 - 1
02_main.ino → 03_main.ino

@@ -1,9 +1,17 @@
 char outputStr[100];
 int16_t averages[AVG_PERIODS];
 
+#define INT_MODE
 
 void loop() {
-#ifdef SCAN_MODE
+#ifdef INT_MODE
+	for(byte ch = LOW_CHANNEL; ch <= NUM_CHANNELS; ch++) {
+		int val = channelVals[ch];
+		sprintf(outputStr, "Channel-%d:%d\t", ch, val);
+		Serial.print(outputStr);
+	}
+	Serial.println();
+#elif SCAN_MODE
 	for(byte i = LOW_CHANNEL; i <= NUM_CHANNELS; i++) {
 		readChannel(i);
 	}

+ 3 - 1
rc_receiver_driving.ino

@@ -9,7 +9,7 @@
 #define OUTPUT_RANGE 255 // The maximum value for PWM output
 ///////////////////////
 
-#define SCAN_DELAY 100 // Delay between updates in ms
+#define SCAN_DELAY 10 // Delay between updates in ms
 #define AVG_PERIODS 10 // Number of periods to average the speed over (reduces random variances)
 
 /////////////////////////////////////////////////////////////////////////
@@ -21,6 +21,8 @@
 
 // Channel pins. Using numbers 1-6 for clarity, so using a bad value in index 0.
 const byte channels[7] = {255, 8,9,10,11,12,13};
+// How long (in microseconds) the channel is being held high for.
+int channelVals[NUM_CHANNELS + 1];
 
 /////////////////////////////////////////////////////////////////////////
 // Channel values