Arduino Led Cube 5x5x5 shift register 74HC595 - arduino-uno

I'm working on an Arduino project led cube 5x5x5 using shift register 74HC595 I write a function to turn one led on or off the problem is when I want to turn on two led in different layer 4 led turn on how I can solve that
#include <ShiftRegister74HC595.h>
// create a global shift register object
// parameters: <number of shift registers> (data pin, clock pin, latch pin)
ShiftRegister74HC595<4> sr(11, 13, 8);
const uint8_t L0 = A0;const uint8_t L1 = A1;
const uint8_t L2 = A2;const uint8_t L3 = A3;
const uint8_t L4 = A4;
static const uint8_t layers[] = {L0,L1,L2,L3,L4};
const int delaytime=10;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
for(int i=0;i<5;i++)
pinMode(layers[i],OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
setLedState(0,L4,true);
setLedState(12,L1,true);
}
void setLedState(int lednum,uint8_t layer,bool state)
{
if(state==true)
{
sr.set(lednum,HIGH);
digitalWrite(layer,HIGH);
}else
{
sr.set(lednum,LOW);
digitalWrite(layer,LOW);
}
}

Related

Issues Calling Functions from Freertos Task (ESP32)

Currently I am having issues with a program running a freertos program. The purpose of the program is to control a stepper motor as well as an led. Implementing the motor control without microstepping does not have any issues as the two tasks take no parameters and call no functions.
However, when I introduce microstepping which requires two nested functions to be called by the move_routine task, the program will not do anything (no led flashing, no motor turning) when it did before. Does anyone have any solutions for this or any reasons on why this shouldn't work? From what I can see it should be fine to call a function from a freertos task.
#include <Arduino.h>
#include <Stepper.h>
/*================PIN DEFINITIONS================*/
#define LEDC_CHANNEL_0 0
#define LEDC_CHANNEL_1 1
#define LEDC_CHANNEL_2 2
#define LEDC_CHANNEL_3 3
const int A1A = 14;
const int A1B = 27;
const int B1A = 26;
const int B2A = 25;
const int ledPin = 33;
/*================VARIABLE DEFINITIONS================*/
int stepnumber = 0;
int Pa; int Pb;
const int stepsPerRev = 200;
Stepper myStepper(stepsPerRev, 14,27,26,25);
/*================Function Definitions================*/
//Analogwrite using LEDC capabilities
void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) {
//calculation of duty cycle
uint32_t duty = (4095/valueMax)*min(value, valueMax);
ledcWrite(channel,duty);
}
void move(int stepnumber, int MAXpower, int wait) {
Pa = (sin(stepnumber*0.098174)*MAXpower);
Pb = (cos(stepnumber*0.098174)*MAXpower);
if (Pa>0)
{
ledcAnalogWrite(LEDC_CHANNEL_0,Pa);
ledcAnalogWrite(LEDC_CHANNEL_1,0);
}
else
{
ledcAnalogWrite(LEDC_CHANNEL_0,0);
ledcAnalogWrite(LEDC_CHANNEL_1,abs(Pa));
}
if (Pb>0)
{
ledcAnalogWrite(LEDC_CHANNEL_2,Pb);
ledcAnalogWrite(LEDC_CHANNEL_3,0);
}
else
{
ledcAnalogWrite(LEDC_CHANNEL_2,0);
ledcAnalogWrite(LEDC_CHANNEL_3,abs(Pb));
}
}
void move_routine(void *parameters) {
while(1) {
for (int i=0; i<3199; i++)
{
stepnumber++;
move(stepnumber,255,250);
}
vTaskDelay(3000/portTICK_PERIOD_MS);
for (int i=0; i<1599; i++)
{
stepnumber--;
move(stepnumber,255,1000);
}
vTaskDelay(3000/portTICK_PERIOD_MS);
}
}
void led_task(void * parameters){
while(1){
digitalWrite(ledPin, HIGH);
vTaskDelay(500/portTICK_PERIOD_MS);
digitalWrite(ledPin, LOW);
vTaskDelay(500/portTICK_PERIOD_MS);
}
}
void setup(){
myStepper.setSpeed(60);
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
xTaskCreatePinnedToCore(
move_routine,
"Move Routine",
8192,
NULL,
1,
NULL,
1
);
xTaskCreatePinnedToCore(
led_task,
"LED Task",
1024,
NULL,
1,
NULL,
1
);
}
void loop(){
}
Expected to see flashing led and motor turning but nothing witnessed
Your two tasks work as it were defined, the problem is your ledcAnalogWrite() function where you are calling ledcWrite() function with nowhere in your code initialise the LEDC with ledcSetup() and ledcAttachPin().
Read the documentation on LED Control(LEDC).

Imposible to replicate pure SPI functions using EPS-IDF functions (spi_device_polling_transmit ecc..)

I'm working with esp-idf and I found this repository that has implemented the Adafruit driver for the PN532 in "plain" esp-idf. This library works very well if I use it as is.
I'm trying to improve the code by changing the SPI functions to use directly the one provided by esp-idf.
I found this documentation (see section 6.1.1.1) and this other documentation (section 2.4.1) that slightly helped me in order to understand how to configure the SPI device, but I'm still missing something because I don't have the right response from PN532 when I use the settings shown below, nor in any other configuration.
So I'm searching for someone that can help me understand better what I'm missing here.
The original functions are:
void pn532_spi_init(pn532_t *obj, uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss)
{
obj->_clk = clk;
obj->_miso = miso;
obj->_mosi = mosi;
obj->_ss = ss;
gpio_pad_select_gpio(obj->_clk);
gpio_pad_select_gpio(obj->_miso);
gpio_pad_select_gpio(obj->_mosi);
gpio_pad_select_gpio(obj->_ss);
gpio_set_direction(obj->_ss, GPIO_MODE_OUTPUT);
gpio_set_level(obj->_ss, 1);
gpio_set_direction(obj->_clk, GPIO_MODE_OUTPUT);
gpio_set_direction(obj->_mosi, GPIO_MODE_OUTPUT);
gpio_set_direction(obj->_miso, GPIO_MODE_INPUT);
}
/**************************************************************************/
/*!
#brief Low-level SPI write wrapper
#param c 8-bit command to write to the SPI bus
*/
/**************************************************************************/
void pn532_spi_write(pn532_t *obj, uint8_t c)
{
int8_t i;
gpio_set_level(obj->_clk, 1);
for (i = 0; i < 8; i++)
{
gpio_set_level(obj->_clk, 0);
if (c & _BV(i))
{
gpio_set_level(obj->_mosi, 1);
}
else
{
gpio_set_level(obj->_mosi, 0);
}
gpio_set_level(obj->_clk, 1);
}
}
/**************************************************************************/
/*!
#brief Low-level SPI read wrapper
#returns The 8-bit value that was read from the SPI bus
*/
/**************************************************************************/
uint8_t pn532_spi_read(pn532_t *obj)
{
int8_t i, x;
x = 0;
gpio_set_level(obj->_clk, 1);
for (i = 0; i < 8; i++)
{
if (gpio_get_level(obj->_miso))
{
x |= _BV(i);
}
gpio_set_level(obj->_clk, 0);
gpio_set_level(obj->_clk, 1);
}
return x;
}
And my changes are:
void pn532_spi_init(pn532_t *obj, spi_host_device_t spiHostDevice, uint8_t ss) {
gpio_set_direction((gpio_num_t) ss, GPIO_MODE_OUTPUT);
gpio_set_level((gpio_num_t) ss, 1);
//Config Frequency and SS GPIO
spi_device_interface_config_t deviceInterfaceConfig = {
.mode = 0, //SPI mode 0
.clock_speed_hz= 1200000, // Uusually 1.2 Mhz
.input_delay_ns = 0,
.spics_io_num = ss,
.flags = (SPI_DEVICE_BIT_LSBFIRST),
.queue_size = 1
};
spi_device_handle_t spiDeviceHandle;
//Attach the pn532 to the SPI bus
ESP_ERROR_CHECK(spi_bus_add_device(spiHostDevice, &deviceInterfaceConfig, &spiDeviceHandle));
obj->spi = spiDeviceHandle;
obj->_ss = ss;
}
void pn532_spi_write(pn532_t *obj, uint8_t data) {
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length = 8;
t.tx_buffer = &data;
//t.flags = SPI_TRANS_CS_KEEP_ACTIVE;
ESP_LOGI(TAG, "send data: 0b%s", toBinary(data,8));
//t.flags = (SPI_TRANS_MODE_OCT | SPI_TRANS_MODE_QIO);
ESP_ERROR_CHECK(spi_device_polling_transmit(obj->spi, &t));
}
uint8_t pn532_spi_read(pn532_t *obj) {
uint8_t data = 1;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length = 8;
t.rxlength = 8;
t.tx_buffer = NULL;
t.rx_buffer = &data;
//t.flags = SPI_TRANS_CS_KEEP_ACTIVE;
//t.flags = (SPI_TRANS_MODE_OCT);
ESP_ERROR_CHECK(spi_device_polling_transmit(obj->spi, &t));
ESP_LOGI(TAG, "read data: 0b%s", toBinary(data,8));
return data;
}
Externally from this function I'm initializing the SPI bus and then calling the pn532 init and begin functions.
spi_bus_config_t spi_config = {
.mosi_io_num= PIN_NUM_MOSI,
.miso_io_num= PIN_NUM_MISO,
.sclk_io_num= PIN_NUM_CLK,
.quadwp_io_num= -1,
.quadhd_io_num= -1,
.max_transfer_sz= 4092
};
//Initialize the SPI bus
ESP_ERROR_CHECK(spi_bus_initialize(HSPI_HOST, &spi_config, SPI_DMA_CH_AUTO));
static pn532_t nfc;
pn532_spi_init(&nfc, HSPI_HOST, GPIO_NUM_25);
pn532_begin(&nfc);
With this configuration, when I try to read from the SPI, the hex that return the PN532 is 0x08, were expecting 0x01 or 0x00. Seem that is a padding problem? The 1 is shifted in the wrong place?
I'm really lost! :(

How to resolve this problem named " 'button' was not declared in this scope " in arduino?

.
.
.
void setup() {
/*
RGB LED 입출력설정
*/
pinMode(R_LED_PIN, OUTPUT);
pinMode(G_LED_PIN, OUTPUT);
pinMode(B_LED_PIN, OUTPUT);
lcd.init(); // LCD 초기화
lcd.backlight(); // LCD 백라이트 켜기(화면 밝아짐)
lcd.setCursor(2,0); // 커서 (2,0)
lcd.print("*INTERRUPT*"); // 글자출력
delay(500);
attachInterrupt(digitalPinToInterrupt(BUTTONPIN), button, FALLING);
/* 인터럽트 설정(아두이노 3번 핀, button 함수 호출, 모드 FALLING */
}
void loop() {
/*
led_color 함수에 Red, Green에 무작위 값과 Blue에는 0을 인자로 전달
delay를 0~99 사이의 무작위 값으로 설정
*/
led_color(random(256), random(256), 0);
int Blue = 0;
delay(random(100));
.
.
.
I can't resolve the problem like a title
in the interrupt zone: attachInterrupt(digitalPinToInterrupt(BUTTONPIN), button, FALLING);
Arduino uno error makes me crazy!!!!!!
Please help me...
You have not shared the whole code but for your understanding I have written code in place of button you have to provide a function checkSwitch.
const byte ledPin = 13;
const byte buttonPin = 2;
// Boolean to represent toggle state
volatile bool toggleState = false;
void checkSwitch() {
// Check status of switch
// Toggle LED if button pressed
if (digitalRead(buttonPin) == LOW) {
// Switch was pressed
// Change state of toggle
toggleState = !toggleState;
// Indicate state on LED
digitalWrite(ledPin, toggleState);
}
}
void setup() {
// Set LED pin as output
pinMode(ledPin, OUTPUT);
// Set switch pin as INPUT with pullup
pinMode(buttonPin, INPUT_PULLUP);
// Attach Interrupt to Interrupt Service Routine
attachInterrupt(digitalPinToInterrupt(buttonPin),checkSwitch, FALLING);
}
void loop() {
// 5-second time delay
Serial.println("Delay Started");
delay(5000);
Serial.println("Delay Finished");
Serial.println("..............");
}

convert analog read to range to time

I'm trying to blink a led with analog sensor between 8 and 40 times a minutes
I have try this code but I realize that I had to convert the valorSensor to time. How is the way to do it?
int led = 13;
int pinAnalogo = A0;
int analogo;
int valorSensor;
void setup() {
pinMode(led, OUTPUT);
}
void loop() {
analogo = analogRead(pinAnalogo);
valorSensor = map(analogo, 0, 1023, 4, 80);
digitalWrite(led, HIGH);
delay(valorSensor);
digitalWrite(led, LOW);
delay(valorSensor);
}
The problem here is not so much the code but biology. To see a blinking (and not just a flicker you will need times from 250ms and up) 24 frames/sec are perceived as motion so to get a "blink" you might start with 4 frames/sec (=250ms)
So my proposal is a blink without delay as function and a tuning parameter (blinkSpeedMultiplyer) for testing
/* Blink without Delay as function
Turns on and off a light emitting diode (LED) connected to a digital pin,
without using the delay() function. This means that other code can run at the
same time without being interrupted by the LED code.*/
// constants won't change. Used here to set a pin number:
const int blinkSpeedMultiplyer = 50; // very low
const int ledPin = 13;
const int pinAnalogo = A0;
// Variables will change:
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long startTime = millis(); // will store last time LED was updated
unsigned long blinkTime; // interval at which to blink (milliseconds)
int analogo;
int valorSensor;
int ledState = LOW; // ledState used to set the LED
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
analogo = analogRead(pinAnalogo);
valorSensor = map(analogo, 0, 1023, 4, 80);
blinkLed(valorSensor); // call the function
}
// Function to blink without blocking delay
void blinkLed(int inValue) {
blinkTime = blinkSpeedMultiplyer * inValue;
if (millis() - startTime >= blinkTime) {
// save the last time you blinked the LED
startTime = millis();
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}

Attiny85 with ArduinoUno for I2c comm

I am working on attiny85 for I2C communication. I have gone through different libraries already like Wire.h, TinyWire.h, tinyWireM.h, tinyWireS.h.
In the start I want to send some byte of data through I2C comm and tried to scope the pin with oscilloscope but its not giving me the appropriate results. Looking on the internet about different ways to make attiny85 work with I2c is really heartless and I could not achieve the task. Finally, I tried to make attiny85 as master and arduino Uno as slave as it was spare in my box.
I tried to make attiny85 as master and send data to arduino and looks the output on serial monitor but its showing zero.
For the reference, the master and slave codes are attached and my task is just simple to check on serial.
Attiny85 as Master
#include <TinyWireM.h>
void setup()
{
TinyWireM.begin();
}
void loop()
{
TinyWireM.begin();
TinyWireM.beginTransmission(0x08);
TinyWireM.send(0x99);
int Byte1 = TinyWireM.endTransmission();
delay(1000);
}
Arduino as Slave
#include <Wire.h>
const byte add = 0x08;
int byte1;
void setup()
{
Wire.begin(add);
Wire.onReceive(receiveEvent);
Serial.begin(9600);
}
void loop()
{
Serial.println ("Data receiving");
Serial.println(byte1);
delay(1000);
}
void receiveEvent(int bytes)
{
byte1 = Wire.read();
}
But I am not able to get the output on serial monitor of arduino.
What am i doing wrong here?
I have used Atiny85 as a slave using TinyWireS lib (https://github.com/nadavmatalon/TinyWireS) some time back and it worked fine.
Below were the pin configurations
ATtiny85 pin 5 with Arduino Uno A4 and
ATtiny85 pin 7 with Arduino Uno A5
Below are my codes
Atiny.
#include "TinyWireS.h"
const byte SLAVE_ADDR = 100;
const byte NUM_BYTES = 4;
volatile byte data = { 0, 1, 2, 3 };
void setup() {
TinyWireS.begin(SLAVE_ADDR);
TinyWireS.onRequest(requestISR);
}
void loop() {}
void requestISR() {
for (byte i=0; i<NUM_BYTES; i++) {
TinyWireS.write(data[i]);
data[i] += 1;
}
}
Uno.
#include <Wire.h>
const byte SLAVE_ADDR = 100;
const byte NUM_BYTES = 4;
byte data[NUM_BYTES] = { 0 };
byte bytesReceived = 0;
unsigned long timeNow = millis();
void setup() {
Serial.begin(9600);
Wire.begin();
Serial.print(F("\n\nSerial is Open\n\n"));
}
void loop() {
if (millis() - timeNow >= 750) { // trigger every 750mS
Wire.requestFrom(SLAVE_ADDR, NUM_BYTES); // request bytes from slave
bytesReceived = Wire.available(); // count how many bytes received
if (bytesReceived == NUM_BYTES) { // if received correct number of bytes...
for (byte i=0; i<NUM_BYTES; i++) data[i] = Wire.read(); // read and store each byte
printData(); // print the received data
} else { // if received wrong number of bytes...
Serial.print(F("\nRequested ")); // print message with how many bytes received
Serial.print(NUM_BYTES);
Serial.print(F(" bytes, but got "));
Serial.print(bytesReceived);
Serial.print(F(" bytes\n"));
}
timeNow = millis(); // mark preset time for next trigger
}
}
void printData() {
Serial.print(F("\n"));
for (byte i=0; i<NUM_BYTES; i++) {
Serial.print(F("Byte["));
Serial.print(i);
Serial.print(F("]: "));
Serial.print(data[i]);
Serial.print(F("\t"));
}
Serial.print(F("\n"));
}

Resources