LPC2138 Blinking LEDS with switches - lpc

I'm trying to make switch 1 when on turns LEDs 1,2,3 on with a delay of 2 sec. When switch 2 is on, LEDs 4,5,6 go on with delay of 2 sec. When switch 3 is on, it changes the delay of leds to .5 sec. Im having trouble with delay time. Here is code so far.
#include<lpc21xx.h>
#define switch_1 (IO0PIN&0X01)
#define switch_2 (IO0PIN&0X02)
#define switch_3 (IO0PIN&0X04)
void delay(int);
int main()
{
PINSEL0=0X00000000;
IO0DIR=0Xfffffff8;
IO0CLR =0x000001F8;
while(1)
{
if(switch_1==1)
{
IO0SET=0x00000038;
delay(2000);
IO0CLR=0x00000038;
delay(2000);
}
if(switch_2==2)
{
IO0SET=0x000001C0;
delay(2000);
IO0CLR=0x000001C0;
delay(2000);
}
if(switch_3==4)
{
delay(500);
}
}
}
void delay(int time)
{
int i,j;
for(i=0;i<100;i++)
for(j=0;j<2000;j++);
}
I tried doing that code and didn't give me the delay time of 2 seconds for switch 1 and switch 2 nor .5 seconds for switch 3.

Related

M5Atom with mutex is down

M5Atom Lite with the following code is down after booting.
The M5 continues rebooting after down.
This code is simple test for multi-task and mutex.
#include <Arduino.h>
SemaphoreHandle_t xMutex = NULL;
volatile int a = 0;
void subprocess(void *pvParameters)
{
for (;;)
{
if (xSemaphoreTake(xMutex, (portTickType)1000) == pdTRUE)
{
Serial.println(2 * a);
a++;
xSemaphoreGive(xMutex);
}
delay(1000);
}
}
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
// Begin task with Core 0
xTaskCreatePinnedToCore(subprocess, "subprocess", 4096, NULL, 1, NULL, 0);
}
void loop()
{
if (xSemaphoreTake(xMutex, (portTickType)1000) == pdTRUE)
{
Serial.println(2 * a + 1);
a++;
xSemaphoreGive(xMutex);
}
delay(1000);
}
M5Atom Lite is a module with ESP32-PICO-D4, Dual Core MCU.
I have the following message via serial monitor.
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
/home/runne/rh/owmoer/kr/uensnpe3r2/-waorrdku/iensop-3l2i-ba-rbduuiilndoe-rl/iebs-pb3u2i-ladredru/iensop-3l2i-ba-rbduuiilndoe-rl/ib--uil/co/eoneidf/frmpotes/s/fueec:14s/ (eQe.ce1en2 (xQeeuive)- assertefvi)-d!
ebrt f) was c
eled a) PC 0xalled 51 oC 0xre 1
ELF file SHA256: 0000000000000000
Backtrace: 0x40084ea0:0x3ffb1f10 0x40085115:0x3ffb1f30 0x40085e51:0x3ffb1f50 0x400d0cc8:0x3ffb1f90 0x400d1f79:0x3ffb1fb0 0x40086125:0x3ffb1fd0
You've not created the semaphore that you're trying to use. You need to create it first in setup(). For example, assuming you want a binary semaphore, created by xSemaphoreCreateBinary():
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
xMutex = xSemaphoreCreateBinary();
// Begin task with Core 0
xTaskCreatePinnedToCore(subprocess, "subprocess", 4096, NULL, 1, NULL, 0);
}
Error handling omitted for simplicity.

Arduino Uno Timing Issues

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.

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.

Node.js SerialPort Arduino Timing Issue

I'm trying to get my Raspberry Pi/Node.js to communicate with an Arduino Uno using node-serialport. I'm having trouble with the following block of code:
Raspberry Pi
var SerialPort = require("serialport").SerialPort;
var serialPort = new SerialPort("/dev/ttyACM0", {
baudrate: 9600
});
serialPort.on("open", function () {
console.log('open');
serialPort.on('data', function(data) {
console.log('data received: ' + data);
});
serialPort.write(new Buffer('4','ascii'), function(err, results) {
console.log('err ' + err);
console.log('results ' + results);
});
});
Arduino
// LED on pin 12
int led = 12;
// Incoming serial data
int data=0;
void setup() {
// Pin 12 set to OUTPUT
pinMode(led, OUTPUT);
// Start listening on the serialport
Serial.begin(9600);
}
void loop() {
if(Serial.available()>0){
// Read from serialport
data = Serial.read();
// Check and see if data received == 4
if(data=='4') {
// Blink the LED 3 times
for(int i=0;i<3;i++){
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led,LOW);
delay(1000);
}
// Reset data to 0
data=0;
}
}
}
I am only able to get the Arduino to blink the LED if I wrap a for loop around the serialPort.write() function. At the 40th loop iteration or so the LED finally starts blinking and will continue blinking until serialPort.write() loop is finished. This leads me to believe that I'm encountering some sort of timing issue. I'm looking for a more elegent (and non-blocking) solution to blinking the LED on the Arduino via the Pi. Any help would be greatly appreciated.
Thanks!
Bobby
The problem had to do with Arduino's "AutoReset" see more here.
I didn't actually disable autoreset... I went ahead and implemented the code I posted above. I require user interaction to trigger SerialPort.write(). This works as long as there is a few seconds between when the serial connection is opened and the first write.
My guess is that new Buffer('4','ascii') is doing an ASCII string, and not an ASCII character. The difference being that you're not sending 4, or 44444444… using your loop but 4\0 or 4\04\04\04\04\04\04\0… using your loop.
So when you do Serial.available(), it returns 2, as it got two byte buffered, but you only read one byte. As the buffer of the Arduino is a circular buffer that gets overwritten with new data over time, what can happen is that you're only reading the \0s, until over time the timings shift and you get to read only the 4s.
My advice would be to either read as many characters as there is in the buffer, or simply discard invalid reads, as Serial.read() return -1 when the buffer is empty:
const int led=12;
void setup() {
pinMode(led, OUTPUT);
Serial.begin(9600);
}
void loop() {
// Read from serialport
int data = Serial.read();
// Check and see if data received == 4
// and thus discard data==-1 or data==`\0`
if(data=='4') {
// Blink the LED 3 times
for(int i=0;i<3;i++){
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led,LOW);
delay(1000);
}
}
}

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