nRF24L01 with interrupt on receiver

I copied from Mr.ForceTronics with some modify, you can check these URL for reference:

youtube: https://www.youtube.com/watch?v=vzWcBAWpTx0

code: http://forcetronic.blogspot.com/2016/07/using-nrf24l01s-irq-pin-to-generate.html

You only act on response. That is the reason why interrupt is useful. The rest time you can rest to save time. On transmitter module, I send one byte of random number. On receiver module, I deploy pin IRQ to trigger interrupt on pin 3.

 nRF24L01_TX_test_c.ino


//********************Transmitter code**************************** 
#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte counter = 1; //used to count the packets sent
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t pAddress = 0xB00B1E5000LL; // Radio pipe addresses for the 2 nodes to communicate.

void setup() 
{
 Serial.begin(57600); //start serial to communicate process
 wirelessSPI.begin(); //Start the nRF24 module
 wirelessSPI.setAutoAck(1); // Ensure autoACK is enabled so rec sends ack packet to let you know it got the transmit packet payload
 wirelessSPI.enableAckPayload(); // Allow optional ack payloads
 wirelessSPI.setPALevel(RF24_PA_LOW);
 wirelessSPI.openWritingPipe(pAddress); // pipe address that we will communicate over, must be the same for each nRF24 module
 wirelessSPI.stopListening(); //transmitter so stop listening for data
 randomSeed(analogRead(0)); //use random ADC value to seed random number algorithm
}

void loop() {
 delay(random(100,5000)); //Generate delay time between 100msec and 5 sec
 long randNumber = random(0, 255);
 counter = byte(randNumber);
 Serial.println("Sending packet"); 
 if (!wirelessSPI.write( &counter, 1 )){ //if the send fails let the user know over serial monitor
 Serial.println("packet delivery failed"); 
 }
 Serial.println(); 
}

 nRF24L01_RX_test_c.ino


#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <avr/sleep.h> //library needed to use AVR based sleep API

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte gotByte = 0; //used to store payload from transmit module
volatile int count = 0; //tracks the number of interrupts from IRQ
int pCount = 0; //tracks what last count value was so know when count has been updated
RF24 wirelessSPI(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI) 
const uint64_t pAddress = 0xB00B1E5000LL; //Create a pipe addresses for the 2 nodes to communicate over, the "LL" is for LongLong type

void setup() {
 wirelessSPI.begin(); //Start the nRF24 module
 wirelessSPI.setAutoAck(1); // Ensure autoACK is enabled so rec sends ack packet to let you know it got the transmit packet payload
 wirelessSPI.enableAckPayload(); //allows you to include payload on ack packet
 wirelessSPI.maskIRQ(1,1,0); //mask all IRQ triggers except for receive (1 is mask, 0 is no mask)
 wirelessSPI.setPALevel(RF24_PA_LOW); //Set power level to low, won't work well at higher levels (interfer with receiver)
 wirelessSPI.openReadingPipe(1,pAddress); //open pipe o for recieving meassages with pipe address
 wirelessSPI.startListening(); // Start listening for messages
 attachInterrupt(1, interruptFunction, FALLING); //Create interrupt: 0 for pin 2 or 1 for pin 3, the name of the interrupt function or ISR, and condition to trigger interrupt
}

void loop() {

if(pCount < count) { //If this is true it means count was interated and another interrupt occurred
 Serial.begin(57600); //start serial to communicate process
 Serial.print("Receive packet number ");
 Serial.print(count); 
 Serial.print(" has content: ");
 Serial.println(gotByte);
 Serial.end(); //have to end serial since it uses interrupts
 pCount = count; 
 }
}

//This is the function called when the interrupt occurs (pin 2 goes high)
//this is often referred to as the interrupt service routine or ISR
//This cannot take any input arguments or return anything
void interruptFunction() {
 count++; //up the receive counter
 while(wirelessSPI.available()) { //get data sent from transmit
 wirelessSPI.read( &gotByte, 1 ); //read one byte of data and store it in gotByte variable
 }
}

Actually it is one-part done while we have total 2 modules here. The transmitter has to send the message all the time while the receiver only works when interrupt is triggered. The ideal is when the receiver makes a request to the transmitter, the transmitter then sends the message. The definition of transmitter and receiver is no longer suitable. The new definition is requester and responser.

 

I am so lazy at this weekend. Maybe nextweek I will be better. I really need a good sleep.

Advertisements

Rotary encoder used as infinite volume knob

I copied this code from Mr.Ralph S Bacon with these URL:
youtube: https://www.youtube.com/watch?v=J9cDEef0IbQ

code: https://dl.dropboxusercontent.com/u/20622434/RotaryEncoderInterrruptsLED.ino

The good thing of this code is using interrupt on pin3. The bad things is that I modified PinLED from pin 11 to pin 13 and it did not change the brightness of the PinLED.

The hardware connection has a note: Vcc –> 3.3V, CLK –> pin3, DT –> pin4, SW –> pin8. The range value will be [0, 100]


// Used for generating interrupts using CLK signal
const int PinA = 3;

// Used for reading DT signal
const int PinB = 4;

// Used for the push button switch
const int PinSW = 8;

// Simple PWM LED pin
#define PinLED 13

// Keep track of last rotary value
int lastCount = 50;

// Updated by the ISR (Interrupt Service Routine)
volatile int virtualPosition = 50;

// ------------------------------------------------------------------
// INTERRUPT INTERRUPT INTERRUPT INTERRUPT INTERRUPT 
// ------------------------------------------------------------------
void isr () {
 static unsigned long lastInterruptTime = 0;
 unsigned long interruptTime = millis();

// If interrupts come faster than 5ms, assume it's a bounce and ignore
 if (interruptTime - lastInterruptTime > 5) {
 if (digitalRead(PinB) == LOW)
 {
 virtualPosition-- ; // Could be -5 or -10
 }
 else {
 virtualPosition++ ; // Could be +5 or +10
 }

// Restrict value from 0 to +100
 virtualPosition = min(100, max(0, virtualPosition));

// Keep track of when we were here last (no more than every 5ms)
 lastInterruptTime = interruptTime;
 }
}

// ------------------------------------------------------------------
// SETUP SETUP SETUP SETUP SETUP SETUP SETUP 
// ------------------------------------------------------------------
void setup() {
 // Just whilst we debug, view output on serial monitor
 Serial.begin(9600);

// Rotary pulses are INPUTs
 pinMode(PinA, INPUT);
 pinMode(PinB, INPUT);
 pinMode(PinLED, OUTPUT);
 analogWrite(PinLED, virtualPosition);

// Switch is floating so use the in-built PULLUP so we don't need a resistor
 pinMode(PinSW, INPUT_PULLUP);

// Attach the routine to service the interrupts
 attachInterrupt(digitalPinToInterrupt(PinA), isr, LOW);

// Ready to go!
 Serial.println("Start");
}

// ------------------------------------------------------------------
// MAIN LOOP MAIN LOOP MAIN LOOP MAIN LOOP MAIN LOOP
// ------------------------------------------------------------------
void loop() {

// Is someone pressing the rotary switch?
 if ((!digitalRead(PinSW))) {
 virtualPosition = 50;
 while (!digitalRead(PinSW))
 delay(10);
 Serial.println("Reset");
 }

// If the current rotary switch position has changed then update everything
 if (virtualPosition != lastCount) {
 
 // Our LED gets brighter or dimmer
 analogWrite(PinLED, virtualPosition);

// Write out to serial monitor the value and direction
 Serial.print(virtualPosition > lastCount ? "Up :" : "Down:");
 Serial.println(virtualPosition);

// Keep track of this new value
 lastCount = virtualPosition ;
 }
}

 

[PA-03c] Read temperature DHT21 with Qt

Another useful code from Vannevar Morgan, you can check these out:
youtube: https://www.youtube.com/watch?v=1PNn63P793Y

github: https://github.com/vannevar-morgan/Qt-Temperature-Sensor

However, I do not use the temperature DS18B20. I use temperature and humidity DHT21. And in Qt code, I use Celcius degree instead of Fahrenheit degree. In Arduino code, I use header file floatToString to display the data to LCD.

 pyqt_dht.ino


/*
 * Date: Wed, 10/05/2017
 * Desc: Read Temperature and Humidity from DHT21
 * Display on LCD
 * Send to PC via serial
 */
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#include "floatToString.h"

#define I2C_ADDR 0x3F 
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

#define DHTPIN 9
#define DHTTYPE DHT21
DHT dht(DHTPIN, DHTTYPE);
float t;
float h;
char bufferstore[20]; // used by floatToString to display on LCD

void setup() {
 delay(1000);
 // Initialize Serial
 Serial.begin(9600); 
 // Initialize DHT
 dht.begin();

// Initialize LCD
 lcd.begin(16,2);
 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
 lcd.setBacklight(HIGH); 
}

void loop() {
 // Read sensor parameter
 h = dht.readHumidity();
 t = dht.readTemperature();
 // Display on LCD
 lcd_display_temp_humid(t,h);
 // Send via serialport
 Serial.print(t);
 Serial.print(",");
 Serial.flush();
 // Delay for next round
 delay(2000);
}

void lcd_display_temp_humid(float temperature, float humidity){
 lcd.clear();
 lcd.print("Tempe: ");
 lcd.print(floatToString(bufferstore, temperature, 2, 5, true));
 lcd.print(" C");
 lcd.setCursor(0,1);
 lcd.print("Humid: ");
 lcd.print(floatToString(bufferstore, humidity, 2, 5, true));
 lcd.print(" %");
}

floatToString.h


// floatToString.h
//
// Tim Hirzel
// tim@growdown.com
// March 2008
// float to string
// 
// If you don't save this as a .h, you will want to remove the default arguments 
// uncomment this first line, and swap it for the next. I don't think keyword arguments compile in .pde files

//char * floatToString(char * outstr, float value, int places, int minwidth=, bool rightjustify) {
char * floatToString(char * outstr, float value, int places, int minwidth=0, bool rightjustify=false) {
 // this is used to write a float value to string, outstr. oustr is also the return value.
 int digit;
 float tens = 0.1;
 int tenscount = 0;
 int i;
 float tempfloat = value;
 int c = 0;
 int charcount = 1;
 int extra = 0;
 // make sure we round properly. this could use pow from <math.h>, but doesn't seem worth the import
 // if this rounding step isn't here, the value 54.321 prints as 54.3209

// calculate rounding term d: 0.5/pow(10,places) 
 float d = 0.5;
 if (value < 0)
 d *= -1.0;
 // divide by ten for each decimal place
 for (i = 0; i < places; i++)
 d/= 10.0; 
 // this small addition, combined with truncation will round our values properly 
 tempfloat += d;

// first get value tens to be the large power of ten less than value 
 if (value < 0)
 tempfloat *= -1.0;
 while ((tens * 10.0) <= tempfloat) {
 tens *= 10.0;
 tenscount += 1;
 }

if (tenscount > 0)
 charcount += tenscount;
 else
 charcount += 1;

if (value < 0)
 charcount += 1;
 charcount += 1 + places;

minwidth += 1; // both count the null final character
 if (minwidth > charcount){ 
 extra = minwidth - charcount;
 charcount = minwidth;
 }

if (extra > 0 and rightjustify) {
 for (int i = 0; i< extra; i++) {
 outstr[c++] = ' ';
 }
 }

// write out the negative if needed
 if (value < 0)
 outstr[c++] = '-';

if (tenscount == 0) 
 outstr[c++] = '0';

for (i=0; i< tenscount; i++) {
 digit = (int) (tempfloat/tens);
 itoa(digit, &outstr[c++], 10);
 tempfloat = tempfloat - ((float)digit * tens);
 tens /= 10.0;
 }

// if no places after decimal, stop now and return

// otherwise, write the point and continue on
 if (places > 0)
 outstr[c++] = '.';


 // now write out each decimal place by shifting digits one by one into the ones place and writing the truncated value
 for (i = 0; i < places; i++) {
 tempfloat *= 10.0; 
 digit = (int) tempfloat;
 itoa(digit, &outstr[c++], 10);
 // once written, subtract off that digit
 tempfloat = tempfloat - (float) digit; 
 }
 if (extra > 0 and not rightjustify) {
 for (int i = 0; i< extra; i++) {
 outstr[c++] = ' ';
 }
 }


 outstr[c++] = '\0';
 return outstr;
}

Till now, I am just a copier without clearly understand how things are done. I have temperature and humidity but only show one of them. The main loop of Arduino has to send the data continuously. It is not practical. The right procedure is when PC sends command to Arduino, Arduino responses. I hope to do better job next time.

PS: remember 10k pick-up resistor of DHT signal pin.

[PA-03b] Control RGB Led with slider Qt

I used the code of Mr.Vannevar Morgan and modified Arduino code in order to display RGB value on LCD I2C. Please check this link to see his youtube tutorial and github code
youtube: https://www.youtube.com/watch?v=5uuFlSzzYsc

github: https://github.com/vannevar-morgan/Qt-RGB-LED

The idea is similiar with the [PA-03a], you send command to Arduino and Arduino does correspondingly. Since we have 3 values of R-G-B so to discriminate them, we have to add prefix ‘r’ for Red, ‘g’ for Green and ‘b’ for Blue before brightness value. Here is my Arduino code:


/*
 * Date: Tue, 09/05/2017
 * Desc: Receive command from python to adjust RGB color
 * Convert message into integer, PWM on pin 9, 10, 11
 * Give feedback message syntax (R,G,B) displayed on LCD
 */
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR 0x3F 
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

#define red_led 9
#define green_led 10
#define blue_led 11
int rgb_val[3];

void setup()
{
 delay(1000);
 // Initialize pinMode
 pinMode(red_led, OUTPUT);
 pinMode(green_led, OUTPUT);
 pinMode(blue_led, OUTPUT);
 setPwmFrequency(red_led, 8); //Set pin 9's PWM frequency to 3906 Hz (31250/8 = 3906)
 setPwmFrequency(green_led, 8);
 setPwmFrequency(blue_led, 8);
 rgb_val[0] = 0; // This is the only way
 rgb_val[1] = 100;
 rgb_val[2] = 0;
 analogWrite(red_led, rgb_val[0]);
 analogWrite(green_led, rgb_val[1]);
 analogWrite(blue_led, rgb_val[2]);

// Initial LCD
 lcd.begin(16,2);
 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
 lcd.setBacklight(HIGH);
 lcd_display_command(rgb_val);
 lcd.setCursor(0,0);
 lcd.print("Initial R-G-B ");
 
 // Initialize serial
 Serial.begin(9600);
}

void loop()
{
 if (Serial.available()){
 char led_specifier = Serial.read();
 int led_brightness = Serial.parseInt();
 write_leds(led_specifier, led_brightness);
 }
}

void write_leds(char led, int brightness)
{
 if (led == 'r'){
 analogWrite(red_led, brightness);
 rgb_val[0] = brightness;
 lcd_display_command(rgb_val);
 return;
 }
 if (led == 'g'){
 analogWrite(green_led, brightness);
 rgb_val[1] = brightness;
 lcd_display_command(rgb_val);
 return;
 }
 if (led == 'b'){
 analogWrite(blue_led, brightness);
 rgb_val[2] = brightness;
 lcd_display_command(rgb_val);
 return;
 } 
 return;
}

// change the frequency of PWM
void setPwmFrequency(int pin, int divisor) {
 byte mode;
 if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
 switch(divisor) {
 case 1: mode = 0x01; break;
 case 8: mode = 0x02; break;
 case 64: mode = 0x03; break;
 case 256: mode = 0x04; break;
 case 1024: mode = 0x05; break;
 default: return;
 }
 if(pin == 5 || pin == 6) {
 TCCR0B = TCCR0B & 0b11111000 | mode;
 } else {
 TCCR1B = TCCR1B & 0b11111000 | mode;
 }
 } else if(pin == 3 || pin == 11) {
 switch(divisor) {
 case 1: mode = 0x01; break;
 case 8: mode = 0x02; break;
 case 32: mode = 0x03; break;
 case 64: mode = 0x04; break;
 case 128: mode = 0x05; break;
 case 256: mode = 0x06; break;
 case 1024: mode = 0x07; break;
 default: return;
 }
 TCCR2B = TCCR2B & 0b11111000 | mode;
 }
}
// display on LCD 16x2
void lcd_display_command(int rgb_value[3]){
 lcd.clear();
 lcd.print("Color code R-G-B");
 lcd.setCursor(0,1);
 String content = String(rgb_value[0]) + "-" + String(rgb_value[1]) + "-" + String(rgb_value[2]);
 lcd.print(content);
}

There are some need-improve things. First, at the initializing state, if you are not happy with my R-G-B value = [0, 100, 0] and you want to change this, you have to change the initial value of the slider. So you need code to update the initial state at the beginning of Qt.

Second, the LCD seems to fade when you are dragging the slider (if you click, LCD displays quickly) so I think there is some uncertainty when you deal with the function slider_value_change. I will follow up this tutorial (maybe feedback message with time logging, yeah that is good, yay me)

Third, only one channel value (Red, Green or Blue) is sent at a time. It is not practical in the real life because you have to send a data block of 3 values. For example you have a color pallet and you pick a point on the pallet, the RGB value will change all of 3 value. I am thinking about sending a number (with binary from for enhancing transfer speed)


(256^2)*R + (256^1)*G + (256^0)*B


and a prefix (like modbus: one byte address, one byte value). So this tutorial will be suspended for further improvement.

[PA-03a] Create GUI with Qt

In this tutorial, we focus on building a GUI that gives command to Arduino and Arduino will display the received command, turn Led on-off and give feedback message. The main content will how to use Qt to make GUI. Easy thing on first, here is the code of Arduino
pyqt_blink_feedback.ino


/*
 * Date: Fri, 05/05/2017
 * Desc: Blink Led 13 when receiving command
 * and give feedback message
 * also display lcd i2c command
 */
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR 0x3F 
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

// Used for pin status
int ledPin = 13;

// Used for serial 
char incomingChar;

void setup() {
 // Initial process
 delay(1000);
 pinMode(ledPin, OUTPUT); // declare LED as output
 digitalWrite(ledPin, LOW);
 Serial.begin(9600);
 Serial.println("Ready for command.");

lcd.begin(16,2);
 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
 lcd.setBacklight(HIGH);
 lcd.clear();
 lcd.print("Waiting command:");
}

void loop(){
 // when characters arrive over the serial port...
 if (Serial.available()){
 // wait a bit for the entire message to arrive
 delay(100);
 while (Serial.available() > 0) {
 incomingChar = Serial.read();
 lcd_display_command(String(incomingChar));
 if (incomingChar == '1'){ 
 digitalWrite(ledPin, HIGH);
 Serial.println("Led is turn on."); 
 } else if (incomingChar == '0'){
 digitalWrite(ledPin, LOW);
 Serial.println("Led is turn off."); 
 } else {
 Serial.println("Error.");
 }
 // Post processing, clear incomingChar
 incomingChar = ' ';
 }
 }
}

void lcd_display_command(String content){
 lcd.clear();
 lcd.print("Received command");
 lcd.setCursor(0,1);
 lcd.print(content);
}

Step 1: download PyQt 4.10 x32 at SourceForge URL: https://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.10/PyQt4-4.10-gpl-Py2.7-Qt4.8.4-x32.exe/download and install to your computer

Step 2: create folder pyqt_blink_command

Open Qt designer, New Form will show up --> pick Dialog without Button --> Create.

Step 2.1: modify the windowTitle of Dialog into Control Led with feedback

Step 2.2: create Text Browser --> Drag and Drop TextBrowser (Display Widget) to Dialog

Step 2.3: create Button --> Drag and Drop PushButton to Dialog --> change Text to Turn on (because initially Led 13 is off)

Step 2.4: save form with name ArduinoLed.ui in folder pyqt_blink_command

Step 3: cmd --> change directory to folder pyqt_blink_command --> convert file .ui to file .py


pyuic4 -x ArduinoLed.ui -o ArduinoLedUI.py

Right click on ArduinoLedUI.py --> Edit with IDLE. We can Run this code for testing first.

Step 4: modify code that is converted from .ui, including: import serial library, write function for button and display the feedback message

Step 4.1: import the serial library at the beginning of the code

[modified ArduinoLedUI.py]


# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'ArduinoLed.ui'
#
# Created: Fri May 05 14:43:31 2017
# by: PyQt4 UI code generator 4.10
#
# WARNING! All changes made in this file will be lost!

import sys, time, serial
from PyQt4 import QtCore, QtGui

try:
 _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
 def _fromUtf8(s):
 return s

try:
 _encoding = QtGui.QApplication.UnicodeUTF8
 def _translate(context, text, disambig):
 return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
 def _translate(context, text, disambig):
 return QtGui.QApplication.translate(context, text, disambig)

class Ui_Dialog(object):
 def setupUi(self, Dialog):
 # declaration for serial port and initialize variable
 self.LedStatus = 0 # Led status showing on-off
 self.arduino = serial.Serial('COM3', 9600)
 txtArduino = self.arduino.readline()
 txt = "Arduino> " + txtArduino
 #
 Dialog.setObjectName(_fromUtf8("Dialog"))
 Dialog.resize(401, 223)
 self.textBrowser = QtGui.QTextBrowser(Dialog)
 self.textBrowser.setGeometry(QtCore.QRect(10, 10, 381, 141))
 self.textBrowser.setObjectName(_fromUtf8("textBrowser"))
 # Set initial content of Text Browser
 self.textBrowser.append(txt)
 #
 self.pushButton = QtGui.QPushButton(Dialog)
 self.pushButton.setGeometry(QtCore.QRect(280, 160, 111, 41))
 self.pushButton.setObjectName(_fromUtf8("pushButton"))

self.retranslateUi(Dialog)
 QtCore.QMetaObject.connectSlotsByName(Dialog)
 # Set the event for button when being clicked
 QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL("clicked()"), self.LedControl)

def retranslateUi(self, Dialog):
 Dialog.setWindowTitle(_translate("Dialog", "Control Led with feedback", None))
 self.pushButton.setText(_translate("Dialog", "Turn on", None))

# Function for exit
 def quit(self):
 sys.exit(app.exec_())

# Function for clicking event
 def LedControl(self):
 if self.LedStatus==0:
 self.LedStatus = 1
 self.pushButton.setText('Turn off')
 self.arduino.write('1')
 txtArduino = self.arduino.readline()
 else:
 self.LedStatus = 0
 self.pushButton.setText('Turn on')
 self.arduino.write('0')
 txtArduino = self.arduino.readline()
 txt = "Arduino> " + txtArduino
 self.textBrowser.append(txt)

if __name__ == "__main__":
 import sys
 app = QtGui.QApplication(sys.argv)
 Dialog = QtGui.QDialog()
 ui = Ui_Dialog()
 ui.setupUi(Dialog)
 Dialog.show()
 sys.exit(app.exec_())

Tabspace will determine the structure of python code so be careful when copying and pasting the following code to your project.

LCD I2C display serial message

This testing module is used to display message received via serial on LCD with I2C driver. The purpose of this module is when you use 2 Arduino boards for broadcasting, one transmitter and one receiver. This module is used by the receiver to test the sending message. And this is the one-step-ahead for module nRF24L01, LoRa, Bluetooth or GSM testing. I give you 2 ways to display: direct display without buffering and buffering display in case you want to modified the message you receive (transfer message to number, interpreting the data, for instance, analog vaule 512 will equal 28ºC and calculating, subtracting offset …)
direct display without buffering


/*
 * Date: Wed, 03/05/2017
 * Desc: Receive message from serial
 * Display to LCD I2c
 * direct display to LCD without buffering
*/
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR 0x3F 
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

void setup()
{
 Serial.begin(9600);
 lcd.begin(16,2);
 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
 lcd.setBacklight(HIGH);
 lcd.clear();
 lcd.print("Waiting message:");
}

void loop()
{
 // when characters arrive over the serial port...
 if (Serial.available()) {
 // wait a bit for the entire message to arrive
 delay(100);
 // clear the screen
 lcd.clear();
 // read all the available characters
 while (Serial.available() > 0) {
 // display each character to the LCD WITHOUT BUFFERING
 lcd.write(Serial.read());
 }
 }
}

 

buffering display


/*
 * Date: Wed, 03/05/2017
 * Desc: Receive message from serial
 * Display to LCD I2c
 * direct display to LCD with buffering
*/
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR 0x3F 
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

// used for serial buffering
#define TERM_CHAR '\n'
#define BUF_LEN 16
int i = 0;
char incomingChar; 
char buf[BUF_LEN];

void setup()
{
 Serial.begin(9600);
 lcd.begin(16,2);
 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
 lcd.setBacklight(HIGH);
 lcd.clear();
 lcd.print("Waiting message:");
}

void loop()
{
 // when characters arrive over the serial port...
 if (Serial.available()) {
 // wait a bit for the entire message to arrive
 delay(100);
 // clean buffer and index
 memset(buf,'\0',BUF_LEN); 
 i = 0; 
 // read all the available characters
 while (Serial.available() > 0) {
 incomingChar = (char) Serial.read();
 if(incomingChar != TERM_CHAR && i != BUF_LEN) 
 buf[i++] = incomingChar;
 else
 break;
 delay(1); // wait for another byte 
 }
 // clear the screen and display message
 lcd.clear();
 lcd.print("Serial message:");
 lcd.setCursor(0,1); // 2nd line 
 lcd.write(buf);
 }
}

you can make the different BUF_LEN (but maximum value will be 128)