Arduino Uno Timing Issues - bluetooth

I have been trying to make a robotic "gutter cleaner" for a school project. I decided to use an Arduino Uno to control the motors. It's only a forward/reverse drive and therefore only has one motor controlling the motion of the robot. There is another motor controlling the "blades" (for lack of a better word) coming out the front to fling the dirt out of the gutter.
I am using a HC-05 Bluetooth module to accept input from a smartphone and a L9110 H-bridge to control the motors separately. There are five functions: forward motion, reverse motion, blades on, stop and "autonomous". Autonomous involves the blades being on with the robot moving forward for 20 seconds, backwards for 10 seconds, repeating until the stop function is called.
The problem is that when I call the function for the autonomous, the HC-06 seems to stop receiving data and the debug println("auto fwd") spams the Serial Monitor. The "auto rev" code debug code isn't even reached. The stop function cannot run as it appears no data is being received so an infinite loop is created.
I've tried using BlinkWithoutDelay here and I honestly have no idea why this isn't working.
#include <SoftwareSerial.h> //Include the "SoftwareSerial" software in the program
#define M1A 5 //tells the software compiler to assign these varibales to these outputs on the Arduino board
#define M1B 9 //M1 motors are controlling the motion
#define M2A 4 //M2 motors control the blades
#define M2B 10
SoftwareSerial BT(3, 2); //Tells the program to assign pins 2 and 3 on the Arduino to send and receive data
void fw(); //Denoting Functions to be used
void bw();
void Stop();
void autonomous();
void bladesOn();
boolean autonom = false; //Variables
boolean blades = false;
unsigned long currentMillis = millis();
unsigned long previousMillis = 0;
const long fwdTime = 20000;
const long revTime = fwdTime/2;
void setup() {
// put your setup code here, to run once:
TCCR1B = (TCCR1B & 0b11111000) | 0x04;
BT.begin(9600);
Serial.begin(9600);
pinMode(M1A, OUTPUT);
pinMode(M1B, OUTPUT);
pinMode(M2A, OUTPUT);
pinMode(M2B, OUTPUT);
}
void loop() {
if (BT.available()) {
char input = BT.read(); //Read the incoming BlueTooth signal
Serial.println(input); //Print the BT signal to the memory
switch (input) { //IF input is 1, do this, IF input is 2, do that
case '1':
fw();
break;
case '2':
bw();
break;
case '3':
autonomous();
blades = 1;
autonom = true;
break;
case '4':
bladesOn();
blades = true;
break;
case '0':
Stop();
autonom = false;
blades = false;
break;
}
}
}
void bw() {
digitalWrite(M1A, 0); //Give an output to the M1A pin
analogWrite(M1B, 255); //Give an output to the M1B pin
digitalWrite(M2A, 0);
analogWrite(M2B, 255);
Serial.println("Backwards");
}
void fw() {
digitalWrite(M1A, 1);
analogWrite(M1B, (255 - 255));
digitalWrite(M2A, 1);
analogWrite(M2B, (255 - 255));
Serial.println("Forwards");
}
void Stop() {
digitalWrite(M1A, 0);
analogWrite(M1B, 0);
digitalWrite(M2A, 0);
analogWrite(M2B, 0);
Serial.println("Stop");
}
void autonomous() {
while (autonom == true) {
if (currentMillis - previousMillis <= fwdTime) {
//When time between last repeat of forwards/reverse and now is less than Time1, go forward
digitalWrite(M1A, 1);
analogWrite(M1B, (255 - 255));
digitalWrite(M2A, 1);
analogWrite(M2B, (255 - 255));
Serial.println("auto fwd");
}
if (currentMillis - previousMillis <= revTime) {
//When time between last repeat of forwards/reverse and now is less than Time2, go reverse
digitalWrite(M1A, 0);
analogWrite(M1B, 255);
digitalWrite(M2A, 0);
analogWrite(M2B, 255);
Serial.println("auto rev");
}
if (currentMillis - previousMillis == revTime) { //Set previoustime to currenttime
previousMillis = currentMillis;
Serial.println("Autonom");
}
}
}
void bladesOn() {
blades = true;
digitalWrite(M2A, 1);
analogWrite(M2B, 0);
Serial.println("Blades");
}
I know this is probably too long to read for some people, but any help would be very much appreciated. If you need more information, don't hesitate to ask.
PS. I am using "Arduino BT Joystick" as the Android app to control the robot, if that helps.
Thank you,
Craig.

Your logic for the autonomous() function is wrong. The arduino will get stuck on the while loop on the second call of the function, as noted by DigitalNinja, as the autonom variable is only updated outside this loop.
Even if it wasn't the case, the currentMillis variable is not being updated anywhere in the code, so the test currentMillis - previousMillis <= fwdTime will always be true.
(Ps: sorry to answer like this, I don't have enough reputation to comment.)

Problems:
autonom() contains a loop while(autonom == true) { ... } which does never terminate because autonom is never set to false within the loop, so the control never returns to caller void loop() { ... } and you never listen to bluetooth commands again.
You do not update currentMillis anywhere, thus your robot would end being stuck trying to go forward/backward forever.
It is inappropriate to write currentMillis - previousMillis == revTime, because generally speaking currentMillis might become larger than previousMillis + revTime without ever being equal. You should write currentMillis - previousMillis >= revTime instead.
Although not really complicated, your code is quite long and I don't have much time to spend over an answer, so I'll try to set you in the right direction by giving you the mock-up of a proper design in pseudo-code. I am confident that you'll be able to use it to your needs.
Please note that in this example '1' sets the autonomous movement forward and '2' sets the autonomous movement backward, and '3' is no longer used. This is because I think your communication protocol should be enriched so to allow for command parameters, e.g.: the duration of movement. Note that you can easily reproduce your previous behaviour for '1' and '2' by setting time = 0.
enum {
STAY_STILL,
MOVE_FORWARD,
MOVE_BACKWARD,
}
#define FORWARD_TIME 20000
#define BACKWARD_TIME (FORWARD_TIME / 2)
byte state = STAY_STILL;
unsigned long startMillis;
void loop() {
currentMillis = millis();
if (BT.available()) {
char input = BT.read();
switch (input) {
case '1':
state = MOVE_FORWARD;
time = FORWARD_TIME;
startMillis = currentMillis;
break;
case '2':
state = MOVE_BACKWARD;
time = BACKWARD_TIME;
startMillis = currentMillis;
break;
// case '3' is pointless: instead of duplicating functionality
// you should modify your communication protocol so to allow
// setting both a direction and the amount of time you want
// the robot to move in such direction. A value of 0 could
// stand for 'forever', all other values could be interpreted
// as seconds.
case '4':
start_blades();
break;
case '5':
stop_blades();
break;
case '0':
state = STAY_STILL;
break;
}
}
if (state == MOVE_FORWARD || state == MOVE_BACKWARD) {
move_robot();
} else if (state == STAY_STILL) {
stop_blades();
stop_robot();
}
delay(10);
}
void start_blades() {
digitalWrite(M2A, 1);
analogWrite(M2B, 0);
Serial.println("start blades");
}
void stop_blades() {
digitalWrite(M2A, 0);
analogWrite(M2B, 0);
Serial.println("stop blades");
}
void stop_robot() {
digitalWrite(M1A, 0);
analogWrite(M1B, 0);
Serial.println("stop wheels");
}
void move_robot() {
// time == 0 : move forever in one direction
// else : move up until deadline
if (time == 0 || currentMillis - startMillis <= time) {
if (state == MOVE_FORWARD) {
fw();
} else if (state == MOVE_BACKWARD) {
bw();
}
} else {
// this will turn off both blades and
// wheels at the next iteration of the loop()
state = STAY_STILL;
}
}
...
// your fw() and bw() functions
...
To conclude, a minor suggestion. In your place, I would change functions like fw(), bw(), start_blades(), stop_blades(), stop_robot() to perform an action only when it is necessary, instead of setting the values and printing stuff mindlessly. In addition to reducing the overhead of long functions, it also avoids printing tons of messages through serial, making debugging easier. This can be achieved by enriching the robot's state with more information, but it falls beyond the scope of the question and this answer.

Well, in the end, I had a variable that was turning itself on and off apparently on its own. So when the due date came in for the project I took out the Auto function completely. Thanks for all your help guys, I mightn't have gotten it, but I learned a bit.

Related

ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] if (ser.find("Error")){

I am trying to use Arduino IDE to detect temperature and pulse rate using LM35 sensor and pulse sensor.
This is the code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#include <SoftwareSerial.h>
float pulse = 0;
float temp = 0;
SoftwareSerial ser(9,10);
String apiKey = "MVLG8S8L6138FCR4";
// Variables
int pulsePin = A0; // Pulse Sensor purple wire connected to analog pin 0
int blinkPin = 7 ; // pin to blink led at each beat
int fadePin = 13; // pin to do fancy classy fading blink at each beat
int fadeRate = 0; // used to fade LED on with PWM on fadePin
// Volatile Variables, used in the interrupt service routine!
volatile int BPM; // int that holds raw Analog in 0. updated every 2mS
volatile int Signal; // holds the incoming raw data
volatile int IBI = 600; // int that holds the time interval between beats! Must be seeded!
volatile boolean Pulse = false; // "True" when User's live heartbeat is detected. "False" when nota "live beat".
volatile boolean QS = false; // becomes true when Arduoino finds a beat.
// Regards Serial OutPut -- Set This Up to your needs
static boolean serialVisual = true; // Set to 'false' by Default. Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse
volatile int rate[10]; // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0; // used to determine pulse timing
volatile unsigned long lastBeatTime = 0; // used to find IBI
volatile int P = 512; // used to find peak in pulse wave, seeded
volatile int T = 512; // used to find trough in pulse wave, seeded
volatile int thresh = 525; // used to find instant moment of heart beat, seeded
volatile int amp = 100; // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true; // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = false; // used to seed rate array so we startup with reasonable BPM
void setup()
{
lcd.begin(16, 2);
pinMode(blinkPin,OUTPUT); // pin that will blink to your heartbeat!
pinMode(fadePin,OUTPUT); // pin that will fade to your heartbeat!
Serial.begin(115200); // we agree to talk fast!
interruptSetup(); // sets up to read Pulse Sensor signal every 2mS
// IF YOU ARE POWERING The Pulse Sensor AT VOLTAGE LESS THAN THE BOARD VOLTAGE,
// UN-COMMENT THE NEXT LINE AND APPLY THAT VOLTAGE TO THE A-REF PIN
// analogReference(EXTERNAL);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Patient Health");
lcd.setCursor(0,1);
lcd.print(" Monitoring ");
delay(4000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Initializing....");
delay(5000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Getting Data....");
ser.begin(9600);
ser.println("AT");
delay(1000);
ser.println("AT+GMR");
delay(1000);
ser.println("AT+CWMODE=3");
delay(1000);
ser.println("AT+RST");
delay(5000);
ser.println("AT+CIPMUX=1");
delay(1000);
String cmd="AT+CWJAP=\"Alexahome\",\"98765432\"";
ser.println(cmd);
delay(1000);
ser.println("AT+CIFSR");
delay(1000);
}
// Where the Magic Happens
void loop()
{
serialOutput();
if (QS == true) // A Heartbeat Was Found
{
// BPM and IBI have been Determined
// Quantified Self "QS" true when arduino finds a heartbeat
fadeRate = 255; // Makes the LED Fade Effect Happen, Set 'fadeRate' Variable to 255 to fade LED with pulse
serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.
QS = false; // reset the Quantified Self flag for next time
}
ledFadeToBeat(); // Makes the LED Fade Effect Happen
delay(20); // take a break
read_temp();
esp_8266();
}
void ledFadeToBeat()
{
fadeRate -= 15; // set LED fade value
fadeRate = constrain(fadeRate,0,255); // keep LED fade value from going into negative numbers!
analogWrite(fadePin,fadeRate); // fade LED
}
void interruptSetup()
{
// Initializes Timer2 to throw an interrupt every 2mS.
TCCR2A = 0x02; // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
TCCR2B = 0x06; // DON'T FORCE COMPARE, 256 PRESCALER
OCR2A = 0X7C; // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
TIMSK2 = 0x02; // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
sei(); // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}
void serialOutput()
{ // Decide How To Output Serial.
if (serialVisual == true)
{
arduinoSerialMonitorVisual('-', Signal); // goes to function that makes Serial Monitor Visualizer
}
else
{
sendDataToSerial('S', Signal); // goes to sendDataToSerial function
}
}
void serialOutputWhenBeatHappens()
{
if (serialVisual == true) // Code to Make the Serial Monitor Visualizer Work
{
Serial.print("*** Heart-Beat Happened *** "); //ASCII Art Madness
Serial.print("BPM: ");
Serial.println(BPM);
}
else
{
sendDataToSerial('B',BPM); // send heart rate with a 'B' prefix
sendDataToSerial('Q',IBI); // send time between beats with a 'Q' prefix
}
}
void arduinoSerialMonitorVisual(char symbol, int data )
{
const int sensorMin = 0; // sensor minimum, discovered through experiment
const int sensorMax = 1024; // sensor maximum, discovered through experiment
int sensorReading = data; // map the sensor range to a range of 12 options:
int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
// do something different depending on the
// range value:
switch (range)
{
case 0:
Serial.println(""); /////ASCII Art Madness
break;
case 1:
Serial.println("---");
break;
case 2:
Serial.println("------");
break;
case 3:
Serial.println("---------");
break;
case 4:
Serial.println("------------");
break;
case 5:
Serial.println("--------------|-");
break;
case 6:
Serial.println("--------------|---");
break;
case 7:
Serial.println("--------------|-------");
break;
case 8:
Serial.println("--------------|----------");
break;
case 9:
Serial.println("--------------|----------------");
break;
case 10:
Serial.println("--------------|-------------------");
break;
case 11:
Serial.println("--------------|-----------------------");
break;
}
}
void sendDataToSerial(char symbol, int data )
{
Serial.print(symbol);
Serial.println(data);
}
ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124
{
cli(); // disable interrupts while we do this
Signal = analogRead(pulsePin); // read the Pulse Sensor
sampleCounter += 2; // keep track of the time in mS with this variable
int N = sampleCounter - lastBeatTime; // monitor the time since the last beat to avoid noise
// find the peak and trough of the pulse wave
if(Signal < thresh && N > (IBI/5)*3) // avoid dichrotic noise by waiting 3/5 of last IBI
{
if (Signal < T) // T is the trough
{
T = Signal; // keep track of lowest point in pulse wave
}
}
if(Signal > thresh && Signal > P)
{ // thresh condition helps avoid noise
P = Signal; // P is the peak
} // keep track of highest point in pulse wave
// NOW IT'S TIME TO LOOK FOR THE HEART BEAT
// signal surges up in value every time there is a pulse
if (N > 250)
{ // avoid high frequency noise
if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
{
Pulse = true; // set the Pulse flag when we think there is a pulse
digitalWrite(blinkPin,HIGH); // turn on pin 13 LED
IBI = sampleCounter - lastBeatTime; // measure time between beats in mS
lastBeatTime = sampleCounter; // keep track of time for next pulse
if(secondBeat)
{ // if this is the second beat, if secondBeat == TRUE
secondBeat = false; // clear secondBeat flag
for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup
{
rate[i] = IBI;
}
}
if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE
{
firstBeat = false; // clear firstBeat flag
secondBeat = true; // set the second beat flag
sei(); // enable interrupts again
return; // IBI value is unreliable so discard it
}
// keep a running total of the last 10 IBI values
word runningTotal = 0; // clear the runningTotal variable
for(int i=0; i<=8; i++)
{ // shift data in the rate array
rate[i] = rate[i+1]; // and drop the oldest IBI value
runningTotal += rate[i]; // add up the 9 oldest IBI values
}
rate[9] = IBI; // add the latest IBI to the rate array
runningTotal += rate[9]; // add the latest IBI to runningTotal
runningTotal /= 10; // average the last 10 IBI values
BPM = 60000/runningTotal; // how many beats can fit into a minute? that's BPM!
QS = true; // set Quantified Self flag
// QS FLAG IS NOT CLEARED INSIDE THIS ISR
pulse = BPM;
}
}
if (Signal < thresh && Pulse == true)
{ // when the values are going down, the beat is over
digitalWrite(blinkPin,LOW); // turn off pin 13 LED
Pulse = false; // reset the Pulse flag so we can do it again
amp = P - T; // get amplitude of the pulse wave
thresh = amp/2 + T; // set thresh at 50% of the amplitude
P = thresh; // reset these for next time
T = thresh;
}
if (N > 2500)
{ // if 2.5 seconds go by without a beat
thresh = 512; // set thresh default
P = 512; // set P default
T = 512; // set T default
lastBeatTime = sampleCounter; // bring the lastBeatTime up to date
firstBeat = true; // set these to avoid noise
secondBeat = false; // when we get the heartbeat back
}
sei(); // enable interrupts when youre done!
}// end isr
void esp_8266()
{
// TCP connection AT+CIPSTART=4,"TCP","184.106.153.149",80
String cmd = "AT+CIPSTART=4,\"TCP\",\"";
cmd += "184.106.153.149"; // api.thingspeak.com
cmd += "\",80";
ser.println(cmd);
Serial.println(cmd);
if (ser.find("Error")){
Serial.println("AT+CIPSTART error");
return;
}
String getStr = "GET /update?api_key=";
getStr += apiKey;
getStr +="&field1=";
getStr +=String(pulse);
getStr +="&field2=";
getStr +=String(temp);
getStr += "\r\n\r\n";
// send data length
cmd = "AT+CIPSEND=4,";
cmd += String(getStr.length());
ser.println(cmd);
Serial.println(cmd);
delay(1000);
ser.print(getStr);
Serial.println(getStr); //thingspeak needs 15 sec delay between updates
delay(3000);
}
void read_temp()
{
int temp_val = analogRead(A1);
float mv = (temp_val/1024.0)*5000;
float cel = mv/10;
temp = (cel*9)/5 + 32;
Serial.print("Temperature:");
Serial.println(temp);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("BPM :");
lcd.setCursor(7,0);
lcd.print(BPM);
lcd.setCursor(0,1);
lcd.print("Temp.:");
lcd.setCursor(7,1);
lcd.print(temp);
lcd.setCursor(13,1);
lcd.print("F");
}
This is the error:
C:\Users\vaadh\OneDrive\Documents\Arduino\testing_LED_blinking\testing_LED_blinking.ino: In function 'void esp_8266()':
C:\Users\vaadh\OneDrive\Documents\Arduino\testing_LED_blinking\testing_LED_blinking.ino:282:21: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
if (ser.find("Error")){
It is a problem of the Arduino core Stream class's find method. The type of the parameter should be const char* but it is char*.
Cast the parameter to char* to indicate to the compiler that it is OK.
ser.find((char*) "Error")

How to use a Shared-Variable

I want to know your opinion on how I coded my QThread.
this part of my code is for handle a PWM for LED display.
The purpose of my QThread is to work as smoothly as possible while changing a value in the QThread else i can watch on LED display a very fast break during the value change, example when i use QMutex.
this is the reason why I chose to use the SIGNAL / SLOT way
When I need to change the brightness that depends on the time or value of a resistance, I use the emit SIGNAL_FUNCTION (qint32 new_value)
Is there a risk of crashing my application using my method?
is there another way more correct to handle this kind of procedure?
I enclose my code below.
#include "luminosite.h"
LUMINOSITE::LUMINOSITE(QObject *parent, qint32 P_PIN_LUMINOSITE) :
QThread(parent)
{
PIN_LUMINOSITE = P_PIN_LUMINOSITE;
VALEUR = 1;
}
void LUMINOSITE::run()
{
qint32 TICK = 0;
while(true)
{
if (TICK == 0)
{
digitalWrite(PIN_LUMINOSITE, LOW);
}
else if (TICK == VALEUR)
{
digitalWrite(PIN_LUMINOSITE, HIGH);
}
TICK++;
if (TICK == 33)
{
TICK = 0;
}
delayMicroseconds(1);
}
}
void LUMINOSITE::CHANGEMENT_VALEUR(qint32 P_VALEUR) // SLOT
{
VALEUR = P_VALEUR;
}
If your question is only "SIGNAL/SLOT are they thread safe ?", read that : http://doc.qt.io/qt-5/threads-qobject.html#signals-and-slots-across-threads
It only depend on the connection type you choose.
You need to choose between Qt::QueuedConnection and Qt::BlockingQueuedConnection

Uinput and Raspberry Pi

I tried to ask this question on the Raspberry Pi forums, but I have received no responses at all. I thought I might query the minds of the StackOverflow community that has been so helpful in the past.
I'm writing a userspace driver for the Raspberry Pi (specifically, may be ported to other platforms later) which makes use of the bcm2835 library (GPIO) and uinput (Linux user-input virtual devices). I need to read GPIO pins and translate their values into simulated keypresses on a virtual keyboard. The GPIO part has been completed, and the translation part is also completed. Unfortunately, the virtual-keyboard part has not been solved. Uinput refuses to cooperate.
Now, the exact same code works perfectly on a Debian desktop machine. The evdev and uinput modules are required, both of which were loaded in all test cases. On the desktop, inputs can be triggered, however, on the Raspberry Pi, I can verify that the GPIO subsystem has registered the input, but the uinput events do not trigger. Does anyone have a lead on what I might do?
Thank you very much, if you need any information, logs, or otherwise, please let me know and I will post them as soon as I can.
This is a complete solution that works for me. I have a custom-made keypad and these are the keys I have defined. Here is the link to original pdf I used.
Of course you can define whatever key you want, just add it to the array.
Note: this code only works with elevated permission.
int allowed_keys[allowed_KEYS_size][2] = {0};
void main()
{
init_keys();
int fd = open_uinput();
int key_evt = getKeyEVT(49); // ASCII code for 1
// simulate key press and key release
emit(fd, EV_KEY, key_evt, 1);
emit(fd, EV_SYN, SYN_REPORT, 0);
emit(fd, EV_KEY, key_evt, 0);
emit(fd, EV_SYN, SYN_REPORT, 0);
}
long int emit(int fd, int type, int code, int val)
{
struct input_event ie;
ie.type = type;
ie.code = code;
ie.value = val;
/* timestamp values below are ignored */
ie.time.tv_sec = 0;
ie.time.tv_usec = 0;
long int y = write(fd, &ie, sizeof(ie));
return y;
}
int open_uinput()
{
int fdui = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if (fdui < 0)
{
printf("uinput fd creation failed!\n");
exit(EXIT_FAILURE);
}
ioctl(fdui, UI_SET_EVBIT, EV_KEY);
ioctl(fdui, UI_SET_EVBIT, EV_SYN); //added by behzad
for (int i = 0; i < allowed_KEYS_size; i++)
ioctl(fdui, UI_SET_KEYBIT, allowed_keys[i][1]);
struct uinput_setup usetup;
memset(&usetup, 0, sizeof(usetup));
usetup.id.bustype = BUS_USB;
usetup.id.vendor = 0x1234; /* sample vendor */
usetup.id.product = 0x5678; /* sample product */
strcpy(usetup.name, "My Keypad. Ver 1.1");
ioctl(fdui, UI_DEV_SETUP, &usetup);
ioctl(fdui, UI_DEV_CREATE);
sleep(2);
return fdui;
}
int getKeyEVT(int k)
{
for (int i = 0; i < allowed_KEYS_size; i++)
{
if (allowed_keys[i][0] == k)
return allowed_keys[i][1];
}
return -1;
}
void init_keys()
{
// Reference:
// https://www.alt-codes.net/arrow_alt_codes.php
// /usr/include/linux/input-event-codes.h
allowed_keys[0][0] = 48; //ASCII ---> 0
allowed_keys[0][1] = KEY_0; //LINUX
allowed_keys[1][0] = 49; //ASCII
allowed_keys[1][1] = KEY_1; //LINUX
allowed_keys[2][0] = 50; //ASCII
allowed_keys[2][1] = KEY_2; //LINUX
allowed_keys[3][0] = 51; //ASCII
allowed_keys[3][1] = KEY_3; //LINUX
}

Arduino Leonardo keyboard cmd

I want access cmd in Windows 7 when a button on the board is pressed using an Arduino as a keyboard:
const int buttonPin = 2;
const int ledPin = 13;
int buttonState = 0;
char ctrlKey = KEY_LEFT_GUI;
void setup() {
// Initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// Initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop(){
// Read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
digitalWrite(ledPin, HIGH);
delay(1000);
Keyboard.press(ctrlKey);
Keyboard.press('r'); // This call runs
Keyboard.println("cmd"); // But here it won't write "cmd"
Keyboard.press('10');
Keyboard.releaseAll();
delay(1000);
}
else
{
digitalWrite(ledPin, LOW);
}
}
I also tried with the methods write(), print(), and press() for each letter individually, but it fails. Mostly it minimize all programs or invite all programs that are pinned in windows toolbar.
What is the problem?
Your code presses SuperR, SuperC, SuperM, SuperD, and then Super along with some null key. You need to release Super before attempting to fill the textbox, and you need to press Enter instead of that strange key once you've filled it.

2 PIR motion sensors +Arduino

My project is to allow automatic lightening by detecting motion using PIR Sensors.
THis is what I want to do :
when the first motion sensor "inputpin" is HIGH which means a motion1 is detected , ledPin1 is set to HIGH.... then I check the signal from the other PIR sensor "inputpin2" if it is HIGH ledPin3 should be HIGH , If it is LOW ledpin2 should be HIGH.
I wrote this code , but what it actually do is after a motion is detected from the first sensor"inputPin" , ledPin3 is set to high as if the second sensor is always HIGH !
Can any one help me with this problem.
Thanks
` ``
int ledPin1 = 13; // choose the pin for the LED
int ledPin2 = 12;
int ledPin3 = 11;
int inputPin = 2; // choose the input pin (for PIR sensor)
int inputPin2 = 1;
int pirState1 = LOW; // we start, assuming no motion detected
int pirState2 = LOW;
int val = 0; // variable for reading the pin status
int val2 = 0;
int pinSpeaker = 10; //Set up a speaker on a PWM pin (digital 9, 10, or 11)
void setup() {
pinMode(ledPin1, OUTPUT); // declare LED as output
pinMode(ledPin2, OUTPUT); // declare LED as output
pinMode(ledPin3, OUTPUT);
pinMode(inputPin, INPUT); // declare sensor 1 as input
pinMode(inputPin2, INPUT); // declare sensor 2 as input
// pinMode(pinSpeaker, OUTPUT);
Serial.begin(9600);
}
void loop(){
val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin1, HIGH); // turn LED ON
delay (1500);
if (pirState1 == LOW) {
// we have just turned on
Serial.println("Motion1 detected!");
// We only want to print on the output change, not state
pirState1 = HIGH;
}
delay (1500);
// check sensor 2 after delay
val2 = digitalRead(inputPin2);
if (val2 == HIGH){
digitalWrite(ledPin2, LOW);
delay(1500);
digitalWrite(ledPin3,HIGH);
//playTone(300, 160);
delay(1500);
if (pirState2 == LOW) {
// we have just turned on
Serial.println("Motion1 from sensor 2 detected!");
// We only want to print on the output change, not state
pirState2 = HIGH;
}
}
if(val2 == LOW){
digitalWrite(ledPin2, HIGH);
//playTone(300, 160);
delay(1500);
digitalWrite(ledPin3,LOW);
delay(1500);
}
} else {
digitalWrite(ledPin1, LOW); // turn LED OFF
delay (1500);
digitalWrite(ledPin2, LOW); // may be already
//playTone(0, 0);
delay(1500);
digitalWrite(ledPin3, LOW); // turn LED OFF
delay (1500);
if (pirState1 == HIGH){
// we have just turned of
Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState1 = LOW;
}
if (pirState2 == HIGH){
// we have just turned of
Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState2 = LOW;
}
}
}
// duration in mSecs, frequency in hertz
void playTone(long duration, int freq) {
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(pinSpeaker,HIGH);
delayMicroseconds(period / 2);
digitalWrite(pinSpeaker, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}
`
Change inputPin2 from 1 to 3 for example. Just don't use the pins 0 or 1 (those assigned for Tx and Rx), hope this works.

Resources