Having some problems with Serial.write in Arduino - arduino

I'm learning Arduino and programming some basic stuff just to exercise, but I'm stuck with a RGB LED. I'll link the code in order for you to see what's happening.
int RGB_R = A5,
RGB_G = A4,
RGB_B = A3;
void setup() {
pinMode(RGB_R, OUTPUT);
pinMode(RGB_G, OUTPUT);
pinMode(RGB_B, OUTPUT);
Serial.begin(9600);
}
void loop() {
for(int i = 0; i < 256; i++){
Serial.write(i);
for(int j = 0; j < 256; j++){
for(int k = 0; k < 256; k++){
RGB_COLOR(i,j,k);
}
}
}
}
void RGB_COLOR(int R, int G, int B){
analogWrite(RGB_R, R);
analogWrite(RGB_G, G);
analogWrite(RGB_B, B);
}
I want to change the color of the RGB slowly as i, j and k increment, but it's changing between 2 colors. Another problem that I'm having is that I can't print in Serial what's the value of i, j and k.
Hope you guys can help me.

you have to provide some delay after setting the RGB_COLOR
because the code excuted fast and you can't see the change add a delay function it will be slower changeing
void loop() {
for(int i = 0; i < 256; i++){
for(int j = 0; j < 256; j++){
for(int k = 0; k < 256; k++){
// sending data to pc
Serial.print("\ti= ");Serial.print(i);
Serial.print("\tj= ");Serial.print(j);
Serial.print("\tk= ");Serial.println(k);
// change the data
RGB_COLOR(i,j,k);
delay(100); // wait for 100 ms
}
}
}
}
update :
you have to connect pins on PWM pin ... if you use arduino uno it will be (10,11,6,5,3) and change the connection
int RGB_R = 10,
RGB_G = 11,
RGB_B = 6;
the full code
connect the pins on (10,11,6) ... because analogWrite only work correctlly with pwm pins
int RGB_R = 10,
RGB_G = 11,
RGB_B = 6;
void setup() {
pinMode(RGB_R, OUTPUT);
pinMode(RGB_G, OUTPUT);
pinMode(RGB_B, OUTPUT);
Serial.begin(9600);
}
void loop() {
for(int i = 0; i < 256; i++){
for(int j = 0; j < 256; j++){
for(int k = 0; k < 256; k++){
// sending data to pc
Serial.print("\ti= ");Serial.print(i);
Serial.print("\tj= ");Serial.print(j);
Serial.print("\tk= ");Serial.println(k);
// change the data
RGB_COLOR(i,j,k);
delay(100); // wait for 100 ms
}
}
}
}
void RGB_COLOR(int R, int G, int B){
analogWrite(RGB_R, R);
analogWrite(RGB_G, G);
analogWrite(RGB_B, B);
}

Related

Arduino ignoring serial interrupts when using FastLED

I have tried several different methods found around the internet, however none of them seem to work. This code works for cases 0-2 but when it goes into case 3 which is the rainbow chase loop, the pressing of the button does not interrupt the loop and move the counter forward. I'm assuming, as usual, I'm missing something stupid so many thanks in advance.
#define FASTLED_ALLOW_INTERRUPTS 1
#define FASTLED_INTERRUPT_RETRY_COUNT 1
#include <FastLED.h>
#define AnalogIn A0
#define SwIn 2
#define LED_Out 12
#define NUM_LEDS 5
int pushCounterz = 0;
volatile int buttonState; // Set volatile for interrupt DO NOT SHAKE!
int lastButtonState;
CRGB leds[NUM_LEDS];
void setup() {
// put your setup code here, to run once:
FastLED.setMaxRefreshRate(250);
FastLED.addLeds<WS2812, LED_Out, GRB>(leds, NUM_LEDS);
pinMode(SwIn, INPUT);
pinMode(LED_Out, OUTPUT);
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB ( 255, 0, 255 );
}
FastLED.show();
delay(120);
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB ( 0, 0, 0 );
}
FastLED.show();
Serial.begin(115200);
Serial.println(pushCounterz);
lastButtonState = digitalRead(SwIn); // Set the button state to the startup state
attachInterrupt((SwIn-2), button_ISR, CHANGE); // Set SwIn button as an interrupt pin // Change to Low???
}
void loop() {
if (pushCounterz != 3) {
FastLED.show();
}
Serial.println(pushCounterz);
delay(120);
}
void button_ISR () {
buttonState = digitalRead(SwIn);
digitalWrite(13, buttonState);
if (buttonState == LOW && buttonState != lastButtonState) {
if (pushCounterz > 3) {
//Serial.println("Reset to 0: ");
pushCounterz = 0;
} else {
pushCounterz = pushCounterz + 1;
//Serial.println("Incerment");
}
//Serial.println(pushCounterz);
switch (pushCounterz) {
case 0:
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB (255, 0, 0);
}
break;
case 1:
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB ( 0, 255, 0);
}
break;
case 2:
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB ( 0, 0, 255);
}
break;
case 3:
theaterChaseRainbow(1,50);
break;
default:
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB ( 0, 0, 0);
}
break;
}
}
lastButtonState = buttonState;
}
// Theater-style crawling lights with rainbow effect
void theaterChaseRainbow(int cycles, int speed) { // TODO direction, duration
for (int j = 0; j < 256 * cycles; j++) { // cycle all 256 colors in the wheel
for (int q = 0; q < 3; q++) {
for (int i = 0; i < NUM_LEDS; i = i + 3) {
int pos = i + q;
leds[pos] = Wheel( (i + j) % 255); //turn every third pixel on
}
FastLED.show();
delay(speed);
for (int i = 0; i < NUM_LEDS; i = i + 3) {
leds[i + q] = CRGB::Black; //turn every third pixel off
}
}
}
}
CRGB Wheel(byte WheelPos) {
if (WheelPos < 85) {
return CRGB(WheelPos * 3, 255 - WheelPos * 3, 0);
}
else if (WheelPos < 170) {
WheelPos -= 85;
return CRGB(255 - WheelPos * 3, 0, WheelPos * 3);
}
else {
WheelPos -= 170;
return CRGB(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
Your issue is not that the button is not changing the value, but rather your code has no exit point if it does; the button will change the value, but nothing in theaterChaseRainbow tells it to stop.
Simply add a check in the method to return out if the button state changes:
// Theater-style crawling lights with rainbow effect
void theaterChaseRainbow(int cycles, int speed) { // TODO direction, duration
for (int j = 0; j < 256 * cycles; j++) { // cycle all 256 colors in the wheel
for (int q = 0; q < 3; q++) {
for (int i = 0; i < NUM_LEDS; i = i + 3) {
int pos = i + q;
leds[pos] = Wheel( (i + j) % 255); //turn every third pixel on
}
FastLED.show();
if (pushCounterz != 3) return; //ADDED THIS HERE*****
delay(speed);
for (int i = 0; i < NUM_LEDS; i = i + 3) {
leds[i + q] = CRGB::Black; //turn every third pixel off
}
}
}
}
In addition, I would suggest simplifying your ISR to just increment the button and not have it handle the logic of the program as well. That should either be contained in the loop method or called from the loop method. This should make for some cleaner and less confusing code, as the ISR's job is simply to adjust the value of the button counter, and the loops job is to deal with the state that the program is currently in.
Also - you can't allow interrupts on AVR, or rather I should say it does nothing. I should put in a warning message when that's happening - AVR/arduino's ISR handling is so slow that even the clock tick ISR would be enough to disrupt writing out WS2812 data (resulting in FastLED cutting the frame off) so I yanked that code out of the avr WS2812 asm implementation. Most arm and esp platforms that FastLED supports do allow for interrupt handling to occur during in the small window between writing out each led's data - courtesy of their higher clock speeds.
If you're using an ARM or ESP based platform, then feel free to ignore this comment (mostly putting it here so folks who stumble on this question in a good search know what's up).
As a reference, the working code with the ISR cleanup. (mind you there is still some serial debugging code in there as I have more work to do with brightness etc)
#define FASTLED_ALLOW_INTERRUPTS 1
#define FASTLED_INTERRUPT_RETRY_COUNT 1
#include <FastLED.h>
#define AnalogIn A0
#define SwIn 2
#define LED_Out 12
#define NUM_LEDS 5
int pushCounterz = 4; // 4 = off
volatile int buttonState; // Set volatile for interrupt DO NOT SHAKE!
int lastButtonState;
CRGB leds[NUM_LEDS];
void setup() {
// put your setup code here, to run once:
FastLED.setMaxRefreshRate(250);
FastLED.addLeds<WS2812, LED_Out, GRB>(leds, NUM_LEDS);
pinMode(SwIn, INPUT);
pinMode(LED_Out, OUTPUT);
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB ( 255, 0, 255 );
}
FastLED.show();
delay(120);
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB ( 0, 0, 0 );
}
FastLED.show();
Serial.begin(19200);
Serial.println(pushCounterz);
lastButtonState = digitalRead(SwIn); // Set the button state to the startup state
attachInterrupt((SwIn-2), button_ISR, LOW); // Set SwIn button as an interrupt pin // Change to Low???
}
void loop() {
// if (pushCounterz != 3) {
//FastLED.show();
//Serial.println(pushCounterz);
// }
//delay(20);
switch (pushCounterz) {
case 0:
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB (255, 0, 0);
}
FastLED.show();
break;
case 1:
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB ( 0, 255, 0);
}
FastLED.show();
break;
case 2:
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB ( 0, 0, 255);
}
FastLED.show();
break;
case 3:
theaterChaseRainbow(1,50);
break;
default:
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB ( 0, 0, 0);
}
FastLED.show();
break;
}
}
void button_ISR () {
buttonState = digitalRead(SwIn);
//digitalWrite(13, buttonState);
if (buttonState == LOW && buttonState != lastButtonState) {
if (pushCounterz > 3 || pushCounterz < 0) {
Serial.println("Reset to 0: ");
pushCounterz = 0;
} else {
pushCounterz = pushCounterz + 1;
Serial.println("Incerment");
}
Serial.println(pushCounterz);
}
lastButtonState = buttonState;
}
// Theater-style crawling lights with rainbow effect
void theaterChaseRainbow(int cycles, int speed) { // TODO direction, duration
for (int j = 0; j < 256 * cycles; j++) { // cycle all 256 colors in the wheel
for (int q = 0; q < 3; q++) {
for (int i = 0; i < NUM_LEDS; i = i + 3) {
int pos = i + q;
leds[pos] = Wheel( (i + j) % 255); //turn every third pixel on
}
FastLED.show();
if (pushCounterz != 3) return;
delay(speed);
for (int i = 0; i < NUM_LEDS; i = i + 3) {
leds[i + q] = CRGB::Black; //turn every third pixel off
}
}
}
}
CRGB Wheel(byte WheelPos) {
if (WheelPos < 85) {
return CRGB(WheelPos * 3, 255 - WheelPos * 3, 0);
}
else if (WheelPos < 170) {
WheelPos -= 85;
return CRGB(255 - WheelPos * 3, 0, WheelPos * 3);
}
else {
WheelPos -= 170;
return CRGB(0, WheelPos * 3, 255 - WheelPos * 3);
}
}

Arduino: for loop not working inside of while loop

I have a set of LEDs 12 in total: 6 are blue, 6 are red. I had for loops that helped with the clutter for turning the LEDs on and off at a set interval. But now I want to make it so it has while loops controlling how long until the LED's speed changes. I have made 2 so far and both of them work but the second I put the for loop inside it doesn't do anything.
int redLEDPins[] = {2,3,4,5,6,7};
int blueLEDPins[] = {8,9,10,11,12,13};
int LED_Amount = 6;
int led_delay = 1000;
unsigned long time_since_last_reset = 0;
int wail = 5000;
int yelp = 3000;
int phaser = 3000;
int hilo = 3000;
void setup() {
for (int i; i < LED_Amount; i++) {
pinMode(redLEDPins[i], OUTPUT);
pinMode(blueLEDPins[i], OUTPUT);
}
Serial.begin(9600);
}
void loop() {
//wail while loop
time_since_last_reset = millis();
while((millis() - time_since_last_reset) < wail) {
led_delay = 250;
Serial.print("delay: ");
Serial.println(led_delay);
digitalWrite(2, HIGH);
delay(500);
digitalWrite(2, LOW);
delay(500);
}
//yelp while loop
time_since_last_reset = millis();
while((millis() - time_since_last_reset) < wail){
led_delay = 50;
Serial.print("delay: ");
Serial.println(led_delay);
for (int i; i < LED_Amount; i++) {
digitalWrite(redLEDPins[i], HIGH);
digitalWrite(blueLEDPins[i], LOW);
Serial.println("Red on ");
Serial.println("Blue off");
}
delay(led_delay);
for (int i; i < LED_Amount; i++){
digitalWrite(redLEDPins[i], LOW);
digitalWrite(blueLEDPins[i], HIGH);
Serial.println("Red off ");
Serial.println("Blue on");
}
delay(led_delay);
}
}
for (**int i**; i < LED_Amount; i++){
digitalWrite(redLEDPins[i],LOW);
digitalWrite(blueLEDPins[i],HIGH);
Serial.println("Red off ");
Serial.println("Blue on");
}
Might that be because you didn't initialize i?

Storing the value read previously until new pulse

I'm currently doing a project on an Arduino Uno. The project is based on receiving an IR Signal from an IR Remote and then based on the signal received, perform other operations.
The problem is that the signal gets reset every time. I want to store the value received from the IR Remote and then resets it if detects another pulse.
Here is my code :
int brojac = 0;
int pinData = 10;
unsigned long lengthHeader;
unsigned long bit;
int byteValue;
int vrime = 1000 ;
int storeValue = 0;
void setup()
{
Serial.begin(9600);
pinMode(pinData, INPUT);
}
void loop() {
lengthHeader = pulseIn(pinData, LOW);
if (lengthHeader > 1500)
{
for (int i = 1; i <= 32; i++) {
bit = pulseIn(pinData, HIGH);
if (i > 16 && i <= 24)
if (bit > 1000)
byteValue = byteValue + (1 << (i - 17));
}
}
Serial.print("byteValue = ");
Serial.println(byteValue);
if(byteValue == 66){
digitalWrite(11,HIGH);
}
else{
digitalWrite(11,LOW);
}
delay(vrime);
byteValue = 0;
delay(250);
}
I got the answer by storing the value in a variable until a new variable is detected.
int pinData = 10;
int led = 11;
unsigned long lengthHeader;
unsigned long bit;
int byteValue;
int storeValue = 0;
int previousValue = 0;
void setup()
{
Serial.begin(9600);
pinMode(pinData, INPUT);
pinMode(led, LOW);
}
void loop() {
lengthHeader = pulseIn(pinData, LOW);
if (lengthHeader > 1500)
{
for (int i = 1; i <= 32; i++) {
bit = pulseIn(pinData, HIGH);
if (i > 16 && i <= 24)
if (bit > 1000)
byteValue = byteValue + (1 << (i - 17));
}
}
Serial.print("byteValue = ");
Serial.println(byteValue);
**storeValue = byteValue;
if (storeValue != 0){
previousValue = storeValue;
}
Serial.print("Previous value = ");
Serial.println(previousValue);**
byteValue = 0;
delay(500);
}

arduino interrupt variable not working

I am a beginner with arduino and I'm trying to make a sinus wave generator. Since I've recently found I can't put everything into main void loop, I'm trying to use interrupts. I have problem with changing variable inside of the interrupt (Delay), I don't know where's the mistake.
Here is my code:
int sine256[] = { //256 sin values from 0 to 2pi
};
int i = 0;
int sensorPin = 7;
int outputPin = 6;
volatile float Delay = 10000;
void setup()
{
Serial.begin(9600);
pinMode(outputPin, OUTPUT);
pinMode(sensorPin, INPUT);
attachInterrupt(digitalPinToInterrupt(sensorPin), freq, RISING);
}
void loop()
{
analogWrite(6,sine256[i]);
i = i + 1;
if(i == 256){
i = 0;
}
Serial.println(Delay);
delayMicroseconds(Delay);
}
void freq() {
Delay = Delay/2;
}
EDIT
Try this:
int sine256[] = { //256 sin values from 0 to 2pi
};
int i = 0;
int sensorPin = 7;
int outputPin = 6;
volatile float Delay = 10000;
void setup()
{
Serial.begin(9600);
pinMode(outputPin, OUTPUT);
pinMode(sensorPin, INPUT);
//attachInterrupt(digitalPinToInterrupt(sensorPin), freq, RISING);
}
void loop()
{
analogWrite(6,sine256[i]);
i = i + 1;
if(i == 256){
i = 0;
}
Serial.println(Delay);
freq();
delay(Delay);
}
void freq() {
Delay = Delay / 2;
}
https://www.arduino.cc/en/Reference/AttachInterrupt
Try taking a look at that.
What model are you using?
The only thing that causes me troubles now is the button; when i press it, it often respond as if i had pressed the button multiple times (2,3 or 4x).
This is my final code for now. Since the execution time for a void loop is 12 microseconds, i've calculated delay required to run a generator on 20,40 & 60Hz.
int sine256[] = { //256 sin values from 0 to 2pi (from 0 to 255)
int i = 0;
int sensorPin = 2;
volatile int outputPin = 7;
volatile float Delay = 1000;
int time1;
int time2;
void setup()
{
Serial.begin(9600);
pinMode(outputPin, OUTPUT);
pinMode(sensorPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(sensorPin), freq, FALLING);
}
void loop()
{
//time1 = micros();
analogWrite(outputPin,sine256[i]);
i = i + 1;
if(i == 256){
i = 0;
}
//time2 = micros();
//Serial.println(time2 - time1);
delay(Delay);
}
void freq() {
outputPin = 6;
if(Delay == 0.02){
analogWrite(6,LOW);
outputPin = 7;
Delay = 1000;
}
if(Delay == 0.04){
Delay = 0.02;
}
if(Delay == 0.09){
Delay = 0.04;
}
if((Delay == 1000)&&(outputPin == 6)){
Delay = 0.09;
}
Serial.println(Delay);
}

arduino nothing printing to serial

I've built an arduino sketch that attempts to do a couple of different lengths of windowing and some simple calculations (mean/variance) on the analog values from a couple of sensors. Previously I had the same code for 1 sensor working as intended but the code below has been expanded with a bunch of little for loops so that everything should run for both sensors now.
I simply can't get anything at all to print to serial - even the two serial prints i put in setup and start of loop just to debug - yet the code compiles and uploads without any errors or warnings.
I apologise for including the whole sketch, I couldn't think how to break it apart to show.
long int currentTime = 0;
long int stopTime[2] = {0,0};
long int shortWindowTime = 0;
int shortVal[2][40];
int reflexWindowStart = 0;
int reflexWindowTime = 0;
int reflexVal[2][500];
int mean[2] = {0,0};
unsigned int variance[2] = {0,0};
int lowVal[2] = {0,0};
int peakVal[2] = {0,0};
int lowIndex[2] = {0,0};
int peakIndex[2] = {0,0};
int stopIndex[2] = {0,0};
boolean stopped[2] = {false,false};
void setup(){
Serial.begin(9600);
Serial.println("wtf?");
for(int i=0;i<2;i++){
for(int j=0;j<40;j++){
shortVal[i][j] = 0;
}
for(int j=0;j<500;j++){
reflexVal[i][j] = 1023;
}
}
}
void loop() {
Serial.println("wtf?");
currentTime = micros();
if(currentTime - shortWindowTime > 500){
shortWindowTime = currentTime;
writeShortWindow();
meanVariance();
if(reflexWindowStart == 0){
reflexWindow();
}
reflexWindowStart++;
if(reflexWindowStart > 9){
reflexWindowStart = 0;
}
}
}
void writeShortWindow(){
for(int i=0;i<2;i++){
for(int j=39; j>0; j--){
shortVal[i][j] = shortVal[i][j-1];
}
int ground = analogRead(A5);
shortVal[0][0] = analogRead(A1);
analogRead(A5);
shortVal[i][0] = analogRead(A2);
}
}
void meanVariance(){
for(int i=0;i<2;i++){
for(int j=0; j<39; j++){
mean[i] = mean[i] + shortVal[i][j];
}
mean[i] = mean[i] / 40;
for(int j=0; j<39; j++){
variance[i] = variance[i] + sq(mean[i] - shortVal[i][j]) ;
}
variance[i] = variance[i] / 40;
}
}
void reflexWindow(){
for(int i=0;i<2;i++){
if(stopped[i] == true){
if((millis() - stopTime[i] > 20) && (peakVal[i] - shortVal[i][0] > 20) && (variance[i] <= 1)){
stopped[i] = false;
stopIndex[i] = 0;
Serial.println("................................NOTstopped");
}
}
}
for(int i=0;i<2;i++){
if(stopped[i] == false){
lowVal[i] = 1023;
peakVal[i] = 0;
for(int j=stopIndex[i]; j>0; j--){
reflexVal[i][j] = reflexVal[i][j-1];
if(reflexVal[i][j] < lowVal[i]){
lowVal[i] = reflexVal[i][j];
lowIndex[i] = j;
}
}
reflexVal[i][0] = shortVal[i][0];
for(int j=lowIndex[i]; j>=0; j--){
if(reflexVal[i][j] > peakVal[i]){
peakVal[i] = reflexVal[i][j];
}
}
}
}
for(int i=0;i<2;i++){
if(stopped[i] == false){
if(peakVal[i] - lowVal[i] >= 50){
Serial.print(i);
Serial.println("...................................stopped");
stopTime[i] = millis();
stopped[i] = true;
}
}
}
for(int i=0;i<2;i++){
if(stopIndex[i] < 499){
stopIndex[i]++;
}
}
Serial.print(shortVal[0][0]);
Serial.print(" ... ");
Serial.print(lowVal[0]);
Serial.print(" ... ");
Serial.print(peakVal[0]);
Serial.print(" ........ ");
Serial.print(shortVal[1][0]);
Serial.print(" ... ");
Serial.print(lowVal[1]);
Serial.print(" ... ");
Serial.println(peakVal[1]);
}
If you have a Leonardo board you will most likely not see the Serial.print in the setup function.
Try changing your setup to this (notice the extra while loop waiting for the Serial)
void setup(){
Serial.begin(9600);
while (!Serial);
Serial.println("wtf?");
for(int i=0;i<2;i++){
for(int j=0;j<40;j++){
shortVal[i][j] = 0;
}
for(int j=0;j<500;j++){
reflexVal[i][j] = 1023;
}
}
}
The reason behind this you can read in the Arduino docs for Leonardo http://arduino.cc/en/Guide/ArduinoLeonardo#toc3 but in short is that Leonardo doesnt resets the serial port when opening the serial stream.
Have you checked your BAUD rate in serial monitor, because if it is different, it will not show anything.
be sure the one in serial monitor and in Serial.begin(<BAUD rate here>) is the same

Resources