Arduino analogWrite() between two pins only working in one direction - arduino

I have a set of leds that are setup every other led reversed so when I apply power one way light 1,3,5... light. Change power and 2,4,6... I'm trying to set the brightness using PWM on the digital pins. Here's my code:
unsigned long flashCount = 0;
bool bSwitch = true;
void setup()
{
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
}
void loop()
{
if((flashCount + 1000) < millis())
{
if(bSwitch)
{
analogWrite(6, 0);
analogWrite(7, 1);
bSwitch = false;
}
else
{
analogWrite(7, 0);
analogWrite(6, 1);
bSwitch = true;
}
flashCount = millis();
}
}
If I change analogWrite to 255 instead of 1, it will switch both sets of leds. If I change analogWrite to 127 or less, only one set will light. If I switch the led wires to the pins, the problem switches to the other set of lights.
The leds are like so:
GPIO pin 6 --------.-LED+.---.-LED+.---.-LED+.---.-LED+.---|
GPIO pin 7 ---.+LED-.---.+LED-.---.+LED-.---.+LED-.--------|

Change the connection of the LEDs to pins that both support PWM.
Not all pins support PWM. The analogWrite documentation specifies which pins depending on which board:
On most Arduino boards (those with the ATmega168 or ATmega328P), this function works on pins 3, 5, 6, 9, 10, and 11. On the Arduino Mega, it works on pins 2 - 13 and 44 - 46. Older Arduino boards with an ATmega8 only support analogWrite() on pins 9, 10, and 11.
The other factor is that analogWrite(255) and analogWrite(0) will revert to driving the output as a digital output. So writing 255 causes both pins to output (one as a digital output and the other in PWM mode). But writing 1 to 127 only causes the PWM capable pin to change.

From arduino's manpages:
Syntax
analogWrite(pin, value)
Parameters
pin: the pin to write to. Allowed data types: int.
value: the duty cycle: between 0 (always off) and 255 (always on). Allowed data types: int
Using an analogWrite with a value of 1 is essentially near-zero. 255 would be full voltage. You're attempting to use analogWrite() as if it was digitalWrite().
Consider using digital write instead in your code: https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/
As for your LED's behavior, it seems like your circuit needs to be debugged as well: Your circuit will only allow current to flow when pin 7 is on. Diodes (Light Emitting Diodes) only allow current in one direction. If you're intending to have the LED's alternate, they should all be oriented with the positives pointing toward their GPIO pin and where they meet they should be grounded with a pull-down resistor.

Related

Arduino - Light is staying on for more than expected duration

Code is suppose to Light the inbuit-LED at Pin 13 whenever Pin 5 is High, however i have encountered couple of problem.
While measuring Voltage though Digital Meter - one pin at arduino GND and other at 1,2,3,4. They are showing some non-zero values. Earlier triggering Pin was 4 and light was staying on all the time.
When Pin 5 is high (by connecting 5V Pin from Arduino to Pin 5) it lights the LED as it should, but if Pin 5 stays high for more than 1/2 second, light stays high for more than 0.5 second even after the Pin 5 is disconnected from 5V Pin.
int buttonState = LOW;
int light = 13;
void setup() {
// put your setup code here, to run once:
pinMode(gateopen,INPUT);
pinMode(light, OUTPUT);
}
void loop()
{
// put your main code here, to run repeatedly:
buttonState = digitalRead(gateopen);
if (buttonState == HIGH)
{
digitalWrite(light, HIGH);
}
else
{
digitalWrite(light, LOW);
}
//delayMicroseconds(500);
}
As suggested earlier, use a pull down resistor. Or change your circuit to active low and use INPUT_PULLUP.
I believe you're using delayMicroSeconds, which means the led is just blinking waaay too fast for your eyes. If you want 'half a second' as you hinted on your query, you would be using delay(500) instead.
You are experiencing electrical noise, just like Juraj said, just put a 220 Ohm pull down resistor

MEGA 2560: Crashes when Adafruit FT6206 ctp function called using code with Interrupt

Arduino MEGA 2560: I want an interrupt to execute when a button push occurs on a rotary encoder. I have the code working. However, if I add a function call to Adafruit's FT6206 library the MEGA 2560 hangs. (Evidence of this is that the Serial.println command text is cut-off mid stream of display.) Why?
Hardware setup: rotary encoder push button has two pins: one side is connected to the interrupt pin with a pull-up for power, and the other side tied to ground.
No other hardware or shield is connected. The hardware set up is only the rotary encoder wired to the MEGA 2560 to demonstrate the issue in its simplest form; however, I have the same issue when the TFT display shield is installed.
The MEGA 2560 is the INLAND brand. The rotary encoder is from Adafruit.
Here is the code:
#include "Adafruit_FT6206.h"
// Global Variables
const byte RotarybuttonPin = 21;
volatile byte Rotarybutton_Pressed_Flag;
TS_Point touchpoint;
Adafruit_FT6206 ctp = Adafruit_FT6206();
void setup() {
ctp.begin(70);
Serial.begin(115200);
pinMode(RotarybuttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(RotarybuttonPin), Button_Pin_ISR, LOW);
}
void Button_Pin_ISR() {Rotarybutton_Pressed_Flag = 1;}
void loop() {
Serial.println("In Loop!");
touchpoint = WAIT_FOR_SCREEN_TOUCH();
}
TS_Point WAIT_FOR_SCREEN_TOUCH() {
CHECK_ROTARY_ENCODER();
Serial.println("Entering 'While'");
//This next line locks the MEGA 2560 up with ctp function call
while (!ctp.touched()) {CHECK_ROTARY_ENCODER();}
return (touchpoint);
}
void CHECK_ROTARY_ENCODER() {
if (Rotarybutton_Pressed_Flag) {
Serial.println("PRESSED");
Rotarybutton_Pressed_Flag = 0;
}
else {Serial.println("NOT PRESSED");}
delay(190);
}
Discovered the issue and wanted to share the solution with the community.
The MEGA2560 has six interrupt pins: 2, 3, 18, 19, 20, 21. However, when using the FT6205 which is part of Adafruit's 2.8" TFT shield, the interrupt pins 20 and 21 become unavailable as they are being used by the I2C bus. Interrupts are limited to pins 2, 3, 18, and 19.
This limitation is a bit problematic as the TFT shield blocks easy access to pins 2 and 3. However, it is possible to share a header pin with the shield with a #22 gauge wire.
Pins 18 and 19 are not blocked by the TFT shield and could be used. However, I want to use these pins for their interrupts in detecting clockwise and counterclockwise rotary encoder movement.

Arduino UNO with LCD, strange readings from rotary encoder

I have an I2C 16x2 LCD display connected to an Arduino Uno's A4 (SDA) and A5 (SCL) pins. No problem with the display, it works properly.
Then I have a rotary encoder connected to pins D3 (INT1) and D4. The INT1 pin is used as interrupt to read the encoder, and the reading is sent via Serial.print() to the Serial monitor. There are debounce CAPs connected to the rotary encoder. The encoder pins use the Arduino's internal pullups.
The interrupt is attached to read encoderPinA when encoderPinB is falling from HIGH to LOW. When turning the rotary clockwise, encoderPinA is LOW, and when turning it counter-clockwise, encoderPinA is HIGH.
Now, when there is nothing in the main loop, I get ++++++++++ signs on the serial monitor when turning the rotary clockwise, and ---------- signs when turning it counter-clockwise, as I should.
But if I uncomment those two lines that print to the LCD, I start to get erratic readings from the rotary encoder, like this: -++-++-++-+++-++-+++-++--+.
What's going on? Is the LCD interfering with interrupt pins?
#define encoderPinA 4
#define encoderPinB 3
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
pinMode(encoderPinA, INPUT_PULLUP);
pinMode(encoderPinB, INPUT_PULLUP);
attachInterrupt (digitalPinToInterrupt(encoderPinB), readEncoder, FALLING);
}
void loop() {
//lcd.setCursor(0, 0);
//lcd.print("test");
}
void readEncoder() {
if (digitalRead(encoderPinA) == LOW) Serial.print("+");
else Serial.print("-");
}
Sorry folks, this problem was clearly a cable related issue.
I was using the same non-shielded flat cable to carry out rotary and lcd signals, and there was some interference, because when I switch to separate cables, the erratic behaviour is gone.

Arduino pull-up resistor not working

I am using an Arduino board to read out the value of a soft potmeter. (a strip that detects touch). This works perfectly fine as long as the strip is being touched (a resistance is added to the current).
When the strip is not touched, a completely random floating number is read by the analog pin. Forums mention that you have to add a pullup/pulldown resistor to cancel this effect, but this does not seem te be working. What is wrong with this code?
int potPin = 2;
int curval = 0;
// detect potmeter value
void setup() {
//enable pullup resistor, but still results in erratic output
//when potmeter is not touched
digitalWrite(potPin, HIGH);
//write to serial
Serial.begin(9600);
}
void loop() {
curval = analogRead(potPin);
// this works when the potmeter is being pressed (displays 0 to 1024)
Serial.println(curval);
delay(150);
}
Change
int potPin = 2;
to
int potPin = A2;
Your original use of "2" in both places is assigning Digital Pin 2 to pull-up and reading from Analog Channel 2. As "2" maps correspondingly to is PortD bit 2 and Analog Channel 2 (aka ADC2) is PortC bit 2. As shown below
digitalWrite(2, HIGH); // Pin D2
curval = analogRead(2); // AMUX Channel 2
where A2 shown below is interpreted as follows
digitalWrite(A2, HIGH); // Pin (A2 aka D16)
curval = analogRead(A2); // AMUX Channel 2 on Pin A2
On an UNO (ATmega328) the analogRead() function will interpret 0-7 as channels and will convert the pins A0 through A7 (D14-D21) to corresponding channels, to read from.
Note:
ADC6 and 7 are not available on the chip used on the UNO.
A0-A7 are alias for Digital 14 through 21. Where the labels A0-A7 are typically used.

Arduino UNO analogRead always returns 1023

So my problem is as title says: Arduino UNO analogRead always returns 1023.
But when I burn the same sketch in Arduino Mega 2650 everything works like a charm.
I have tried to change Atmel chips on the UNO, have tried like 3 of them (ATMEGA328P-PU) and nothing changes.
I'm trying to count signals from a hall effect sensor and display the count on a 7 segment display.
Here is the code:
#include "SevSeg.h"
SevSeg sevseg;
volatile int rpmcount;
void setup() {
Serial.begin(9600);
pinMode(2,INPUT_PULLUP);
rpmcount = 0;
sevseg.Begin(1,3,4,5,6,7,8,9,10,11,12,13);
}
int border=15;
void loop() {
int tmp=0;
tmp = analogRead(0);
if(!digitalRead(2))rpmcount=0;
Serial.println(tmp,DEC);
if(tmp<=border && res >border){
rpmcount++;
if(rpmcount>9999)rpmcount=0;
}
res=tmp;
sevseg.NewNum(rpmcount,(byte) 0);
sevseg.PrintOutput();
}
Any help would be much appreciated
This sounds to me as if you had the internal pullup resistor on the ADC pin enabled.
generic checklist:
ACD bit in ACSR is 0 (comparator enable)
MUX bits in ADMUX set properly
correct AREF selected
ADC pin set as input
internal pull up resistors are deselected

Resources