0

I have written a simple sketch that takes values via serial communication through a Python script.
Here's the code-

#define LEDPin 13  

void setup() {
Serial.begin(9600); 
pinMode(LEDPin, OUTPUT);
Serial.println("Ready"); 
}

void loop() {
char inByte = ' ';
if(Serial.available()){ 
 inByte = Serial.read();
}
if (inByte == 'L')
 digitalWrite(LEDPin, HIGH);
if (inByte == 'R')
 digitalWrite(LEDPin, HIGH);
if (inByte == 'S')
 digitalWrite(LEDPin, LOW);
}

Now this code runs perfectly fine with my python script. No problems at all. But When I add code for my L293D motor driver module, like this -

int E1 = 6;
int Left= 5;
int Right = 4;
char data = ' ';

void setup()
{
  pinMode(E1, OUTPUT); 
  pinMode(Left, OUTPUT);  
  pinMode(Right, OUTPUT);
  pinMode(13, OUTPUT);
  Serial.begin(9600);

  }

  void loop(){
    if (Serial.available()>0){
      data = Serial.read();
    }
    if (data =='L'){
      digitalWrite(E1, HIGH);
      digitalWrite(Left, HIGH);
      delay(2000);
      digitalWrite(Left, LOW);
      digitalWrite(E1, LOW);
      digitalWrite(13, HIGH);
    }
     if (data == 'R') {
      digitalWrite(E1, HIGH);
      digitalWrite(Right, HIGH);
      delay(2000);
      digitalWrite(Right, LOW);
      digitalWrite(E1, LOW);
      digitalWrite(13, HIGH);
    }
     if(data == 'S'){
      digitalWrite(E1,LOW);
      digitalWrite(Right, LOW);
      digitalWrite(Left, LOW);
      digitalWrite(13, LOW);
    }

     }

With this code added, the sketch, takes the first value it recieves, for example L, and then would go on executing the if block for that particular value ONLY. Even if the valueschange, still the same code block gets repeated. If I reset the Arduino, using the reset button, again the first value it recieves it starts executing the conditions of the same value and not the rest of the sketch.

P.S- I have attached the capacitor between the pins 5v and RESET.

EDIT

I put ser.readline() in my python script and found that no matter what the script only sends S to the Arduino. Even if the other two conditions are being satisfied, only S is send, and then suddenly, either L or R will be sent and then thats it. No more sending from the script.

Here's my script-

import numpy as np
import cv2
import serial
ser = serial.Serial('COM3',9600,writeTimeout = 0)
def f(x): return
cv2.namedWindow('Thresholding Control')

# create trackbars for color change
cv2.createTrackbar('High H','Thresholding Control',179,179, f)
cv2.createTrackbar('Low H','Thresholding Control',0,179, f)
cv2.createTrackbar('High S','Thresholding Control',255,255, f)
cv2.createTrackbar('Low S','Thresholding Control',0,255, f)
cv2.createTrackbar('High V','Thresholding Control',255,255, f)
cv2.createTrackbar('Low V','Thresholding Control',0,255, f)
cv2.createTrackbar('Guassian Blur','Thresholding Control',0,99, f)

cap = cv2.VideoCapture(0)
while(True):
  ret, image = cap.read()
  HSV = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
  # Getting trackbar values
  highH = cv2.getTrackbarPos('High H','Thresholding Control')
  lowH = cv2.getTrackbarPos('Low H','Thresholding Control')
  highS = cv2.getTrackbarPos('High S','Thresholding Control')
  lowS = cv2.getTrackbarPos('Low S','Thresholding Control')
  highV = cv2.getTrackbarPos('High V','Thresholding Control')
  lowV = cv2.getTrackbarPos('Low V','Thresholding Control')
  # Thresholding the image.
  thresh = cv2.inRange( HSV, (lowH, lowS, lowV), (highH, highS, highV))
  blurVal = cv2.getTrackbarPos('Guassian Blur','Thresholding Control')
  if(blurVal%2==0):
      blurVal=blurVal+1
  thresh_smooth = cv2.GaussianBlur(thresh, (blurVal, blurVal), 0)
  #Defining the kernel to be used for Morphological ops.
  kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
  # Applying Opening and Closing.
  thresh_smooth = cv2.morphologyEx(thresh_smooth,cv2.MORPH_OPEN,kernel)
  thresh_smooth = cv2.morphologyEx(thresh_smooth, cv2.MORPH_CLOSE, kernel)

  #(minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(thresh_smooth)
  eleR = np.count_nonzero(thresh_smooth[0:480, 320:550])
  eleL = np.count_nonzero(thresh_smooth[0:480, 0:320])
  eleO = np.count_nonzero(thresh_smooth[0:480, 550:640])
  if (eleL>eleR and eleL>eleO and eleL!= (eleR+eleO)):
     cv2.putText(image,"Left Turn", (320,240), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
     print ('L')
  elif (eleO>eleR and eleO>eleL):
     cv2.putText(image,"Right Turn", (240,320), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
     print ('R')
  else:
     cv2.putText(image,"Straight", (240,320), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
     print ('S')
  cv2.imshow("BGR", image)
  cv2.imshow("Thresholded", thresh_smooth)
  print ser.readline();
  if cv2.waitKey(1) & 0xFF == ord('q'):
        break
#cv2.imwrite('ImG.png', thresh_smooth)
cap.release()
cv2.destroyAllWindows()
  • One uses inByte and the other uses data? Also; are there any motors attached? Motors use a lot of current and can create a lot on electrical noise, which could make the Arduino freeze or reset. – Gerben Jun 28 '16 at 15:04
  • @Gerben oh that's my fault, actually they are two different sketches I wrote, they are mostly identical except for variable names. Anyways, no there's only one motor attached. – YaddyVirus Jun 28 '16 at 15:07
  • Please post the actual entire sketch that you are having problems with. – Majenko Jun 28 '16 at 15:08
  • How exactly are you updating the value received through serial? Also is the code exactly the same between Arduino sketches as I see you use a different variable to compare for the motor driver. – RSM Jun 28 '16 at 15:08
  • 2
    Have you tried adding some debugging (Serial.println()) to get some visual feedback about how your program flow is working? – Majenko Jun 28 '16 at 15:27
1

You have got quite a bit of difference between the two codes.

In your first code you declare char inByte = ' '; at the beginning of void loop. This means that each time you run through the loop it clears the value which you assign the Serial value to.

In the second code you declare data as a global variable outside of loop.

What that means is that you first code basically allows a one-shot reaction to a Serial value because it clears the value at the beginning of loop. Thus it only goes into an if() statement once.

Whereas your second code will retain the value that it received at Serial.read() the first time. Thus it will continue to run the matching if statement.

What you could do is after each matched if() statement you do data = ' '; or at the beginning of loop you can clear it.

Also you might be missing the updates from your python script because of the delays during motor control. Also Gerben is correct about there possibly being issues with the motor drivers affecting the Arduino.

  • I tried putting the data = ' ' statement in all the possible places. Wherever I place it, the sketch stops working – YaddyVirus Jul 1 '16 at 11:43
0

3 things:

1: your delay statement is worrying, I'd highly recommend parallel coding in this case.

2: you don't have a "data = ' ';" statement in your loop function of the second code, but you do in the first. Is this intentional?

3: if your arduino receives Serial while executing Delay, you mustn't pour in more than the buffer.

  • I've removed the delay but that didn't help – YaddyVirus Jul 1 '16 at 11:47
0

Okay I figured it out. Putting what I did here, for people who are curious and for those who need help.

It was probably the Arduino, autoresetoverserialcomm, for some reason the Arduino auto-resets whenever you send a value over the serial comm to the Arduino from a computer, not from the Serial port (obviously). I knew of this earlier, and another one of my script which also sends data to the Arduino was working fine with this setup.

What I did? I just put a 10µ capacitor between the RESET and the GND pins. That didn't work initially, but I tried putting the +ve of the capacitor in the GND pin and -ve in the RESET pin and voila! The script started working just fine.

I guess this wasn't a programming issue at all, but an issue of the Arduino and the script not being able to contact each other.

I still am not sure as to what was causing the problem or whether what I have done is a permanent fix, or even a fix at all, but my problem seems to have been solved. I'll keep updating the post.

Suggestions and discussions are always welcome!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.