0

I call an API in Python and it gives as output as a single digit and an Arduino program receives this number over serial and displays it on a 7-segment display.

I wrote a different program in which Arduino sends the data and a Python program receives it. That worked but the following program is not working. What is the problem?

I am using Python 3 and Arduino Uno.

Python program:

import serial ,requests, json, time 
arduino = serial.Serial('COM1', 9600, timeout=.1)
time.sleep(1)
response = requests.get("https://traffic.cit.api.here.com/traffic/6.1/flow.json?bbox=12.9808%2C77.5759%3B12.9803%2C77.5767&app_id=zbvY0tdRs089c3ZTKqWR&app_code=pxAtGksNBgVD9V5XF5nEzA",)
#CALLING API
response.content.decode("utf-8")
data = response.json()
text = str(data) #CONVERSION TO STRING
l = len(text)
for i in range(0,l): #Taking out the number
    if text[i] == 'J':
        j = text[i + 5]
        print (j)
        arduino.write(j) #writing over serial
        break

Arduino program:

int a=2;
int b=3;
int c=4;
int d=5;
int e=6;
int f=7;
int g=8;
int h=9;
int rx_byte = 0;

void setup() {
  Serial.begin(9600);
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
  pinMode(h, OUTPUT);
  digitalWrite(h, 0);  // start with the "dot" off
}

void loop() {
  if (Serial.available() > 0) {
    rx_byte = Serial.read(); //reading serial
    switch (rx_byte) {
    case 0:
      zero();
      break;
    case 1:
      one();
      break;
    case 2:
      two();
      break;
    case 3:
      three();
      break;
    case 4:
      four();
      break;
    case 5:
      five();
      break;
    case 6:
      six();
      break;
    case 7:
      seven();
      break;
    case 8:
      eight();
      break;
    case 9:
      nine();
      break;
    }
  }
}

// write '9'

void eight() {
  digitalWrite(a, 1);
  digitalWrite(b, 1);
  digitalWrite(c, 1);
  digitalWrite(d, 1);
  digitalWrite(e, 1);
  digitalWrite(f, 1);
  digitalWrite(g, 1);


}
void seven() {
  digitalWrite(a, 1);
  digitalWrite(b, 1);
  digitalWrite(c, 1);
  digitalWrite(d, 0);
  digitalWrite(e, 0);
  digitalWrite(f, 0);
  digitalWrite(g, 0);

}
void six() {
  digitalWrite(a, 1);
  digitalWrite(b, 0);
  digitalWrite(c, 1);
  digitalWrite(d, 1);
  digitalWrite(e, 1);
  digitalWrite(f, 1);
  digitalWrite(g, 1);
}
void five() {
  digitalWrite(a, 1);
  digitalWrite(b, 0);
  digitalWrite(c, 1);
  digitalWrite(d, 1);
  digitalWrite(e, 0);
  digitalWrite(f, 1);
  digitalWrite(g, 1);

}
void four() {
  digitalWrite(a, 0);
  digitalWrite(b, 1);
  digitalWrite(c, 1);
  digitalWrite(d, 0);
  digitalWrite(e, 0);
  digitalWrite(f, 1);
  digitalWrite(g, 1);
}
void three() {
  digitalWrite(a, 1);
  digitalWrite(b, 1);
  digitalWrite(c, 1);
  digitalWrite(d, 1);
  digitalWrite(e, 0);
  digitalWrite(f, 0);
  digitalWrite(g, 1);

}
void two() {
  digitalWrite(a, 1);
  digitalWrite(b, 1);
  digitalWrite(c, 0);
  digitalWrite(d, 1);
  digitalWrite(e, 1);
  digitalWrite(f, 0);
  digitalWrite(g, 1);
}
void one() {
  digitalWrite(a, 0);
  digitalWrite(b, 1);
  digitalWrite(c, 1);
  digitalWrite(d, 0);
  digitalWrite(e, 0);
  digitalWrite(f, 0);
  digitalWrite(g, 0);

}
void zero() {
  digitalWrite(a, 1);
  digitalWrite(b, 1);
  digitalWrite(c, 1);
  digitalWrite(d, 1);
  digitalWrite(e, 1);
  digitalWrite(f, 1);
  digitalWrite(g, 0);

}
void nine() {
  digitalWrite(a, 1);
  digitalWrite(b, 1);
  digitalWrite(c, 1);
  digitalWrite(d, 0);
  digitalWrite(e, 0);
  digitalWrite(f, 1);
  digitalWrite(g, 1);

}

I am quite new to programming. Please help.

2 Answers 2

1

The python code

j = text[i + 5]
print (j)
arduino.write(j)

Is sending a single text character between '0' and '9', ascii values 48 to 58.

The c code

rx_byte = Serial.read(); //reading serial
switch (rx_byte) {
  case 0:

is looking for absolute values between 0 and 9.

There are two easy options to fix this, option 1 change the case statement to look for the correct values:

rx_byte = Serial.read(); //reading serial
switch (rx_byte) {
  case '0':

or option 2, rely on the fact that the ascii for the numbers is always 48 more than the number represented and subtract that:

rx_byte = Serial.read() - '0'; //reading serial
switch (rx_byte) {
  case 0:

-'0' and -48 would have exactly the same effect here only by using '0' it makes it clear we are offsetting by the ascii value of a 0 rather than by some other randomly created number. It also saves you having to remember what the correct value is for 0.

Generally since you are using the value in a case statement I'd recommend the first option, it's a little more intuitive and avoids an extra calculation that can look a little odd if you are new to programming. The reason I mentioned the second option is that this is the method you would use if you wanted to use the rx_byte value as the index in an array for any reason.

0

I think you are sending ASCII values 0 - 9 over serial. This is a bad idea, because they can be interpreted as control codes, always send printable characters. So in this case send '0' to '9'.

Also you could make you code much smaller if you used arrays.

For instance

int pins[8] = {2,3,4,5,6,7,8,9};
int TheData [8][8] = 
{
    {1,1,1,1,1,1,0,0}, // 0
    {0,1,1,0,0,0,0,0}, // 1
    // etc
};
void write (int number)
{
    for (int i = 0; i < 7; i++)
    {  
       digitalWrite (pins[i], TheData[number][i]);
    }
}

I'll let you figure out how to reduce setup to less than 3 lines :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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