I am using PWM on an arduino due board which uses SAM3X8E(cortex-m3) microcontroller. When I use PWM enable and disable on this board, the waveform goes analog on disabling the channel, instead of staying at 0 or 1. Please see the attached waveform. I tried the code by directly writing to registers also, but it was the same. I also tried a 4.7k pulldown resistor at pwm output, but got the same results. Please tell me how to fix it in software.
If a hardware solution is also possible with some external components, that is also ok. Scope images are attached. The blue scope output is for line 34 (PC02) and yellow for line 35 (PC03).
// include all arduino libraries here.. these are only accepted from ino files.
#include <Arduino.h>
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
void setup() {
// put your setup code here, to run once:
pmc_enable_periph_clk (PWM_INTERFACE_ID) ; // turn on clocking to PWM unit
PWMC_ConfigureChannel (PWM, 0, 1, 0, PWM_CMR_CPOL) ; // PWM channel 0, clock = MCLK/2 = 42MHz
PWMC_SetPeriod (PWM, 0, 700) ; // period = 700 pwm clocks (60kHz)
PWMC_SetDutyCycle (PWM, 0, 80*700/100) ; // duty set to 80%
PWMC_EnableChannel (PWM, 0) ; // enable
// Configure pin 34 (PC2) to be driven by peripheral B (PWM channel 0 L)
// enable pin PC02 and PC03, they are complimentary
PIOC->PIO_PDR = 0xC ; // disable PIO control
PIOC->PIO_IDR = 0xC ; // disable PIO interrupts
PIOC->PIO_ABSR |= 0xC ; // switch to B peripheral
}
void loop() {
// put your main code here, to run repeatedly:
// From these settings, I got these numbers from the scope - 13.3us on time and 3.32us off time
//
PWMC_EnableChannel (PWM, 0) ; // enable
delayMicroseconds(100);
PWMC_DisableChannel (PWM, 0) ; // enable
delayMicroseconds(100);
}
Ans here's the scope images:
It takes some time to disable the channel.
Try to add a waiting loop after disabling:
void loop() {
PWMC_EnableChannel (PWM, 0) ; // enable
delayMicroseconds(100);
PWMC_DisableChannel (PWM, 0) ; // disable
while ((PWM->PWMC_SR & 1) != 0); //add this
delayMicroseconds(100);
}
Related
I am trying to complete an arduino project which uses RFID cards to prompt a DFPlayer mini to play tracks. (The original project is called Juuke).
I have near-on everything working but am having a problem calling the DFPlayer to play from specific folders. It seems the playFolder instruction does not work at all (neither does the playLargeFolder or the playMP3folder). Currently the only instructions I seem to be able to get it to respond to are myDFPlayer.play and myDFPlayer.loopFolder
The project is supposed to work as follows:
each RFID card is programmed with a number,
when you scan and RFID card, it reads the number
it plays the mp3 track from the SDcard with that number (4-digit file name prefixed with zeros)
As far as I can tell the myDFPlayer.play instruction is working, but that seems to play the file based on what order it was added to the SD card, rather than by reading the file name?
The actual situation I am trying account for is that some of the mp3 files are 'singles' so it only needs to play one track. This works fine with the myDFPlayer.play instruction (as long as they were added to the SDcard in the order expected by the filename).
However, other mp3 files are 'albums' so when I scan the RFID I'd like it to open a folder with a group of mp3 files, and loop through all the files in that folder once before stopping.
My plan is to have all the 'singles' in folder with the name 80, if the RFID card number is above 80, the DFPlayer will open folder 80 and play the file with the corresponding filename to the number of the RFID card e.g. if I present RFID card '93', the DFPlayer will open folder 80 and play file 0093.mp3
All the folders below 80 will be 'album folders'. So if I present an RFID card with number below 80 , the DFPlayer will open the folder with the corresponding file name and play track 1 before looping through each file in that folder once, then stopping. e.g. if I present RFID card '42', the DFPlayer will open Folder 42 and play track 1.
Currently, I cannot get the DFPlayer to respond to the instruction myDFPlayer.playFolder in any format. Neither does it respond to myDFPlayer.playMP3Folder or myDFPlayer.playLargeFolder.
Things I have considered and accounted for...
I am adding the mp3 files from my Mac, I am using dot_clean to clean the SD card before putting it into the DFPlayer.
I have tried every variation of folder and file names (4-digit zero prefixed e.g. 0034; 3-digit zero prefixed e.g. 034; folders with 2digit zero prefixed e.g. 07) Nothing seems to work.
Rather than use the number from the RFID card I have just hard coded it to play a specific folder whatever card is there (i.e. myDFPlayer.playFolder(2,1) and the DFPlayer does not respond.
Moving to a Windows machine, formatting the SD card (exFAT is the only format option I get?) an re-adding the mp3 files.
putting the mp3 files in a root file labelled 'mp3'.
having only files on the SD card that are labelled 01 , 02 , 03 etc
The serial monitor shows that the code is working fine except for the bit where the DFPlayer is supposed to find the folder and play the file. There is a small LED on the DF Player that seems to indicate when it is playing a file, that LED does not turn on at all when the playFolder instruction is being given.
This is the code... I have tried a lot of variations in the //PLAY SONG section.
/*
Thanks to Original Author: ryand1011 (https://github.com/ryand1011)
Edited by Ananords -
See: https://github.com/miguelbalboa/rfid/tree/master/examples/rfid_write_personal_data
Uses MIFARE RFID card using RFID-RC522 reader
Uses MFRC522 - Library
-----------------------------------------------------------------------------------------
MFRC522 Arduino Arduino Arduino Arduino Arduino
Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
Signal Pin Pin Pin Pin Pin Pin
-----------------------------------------------------------------------------------------
RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
SPI SS SDA(SS) 10 53 D10 10 10
SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
PS: IF THE PLAYER FAILS TO START WHEN THE SERIAL MONITOR IS NOT OPEN, TRY TO COMMENT OUT Serial.begin(115200);
*/
#include <SPI.h>
#include <MFRC522.h>
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
const int playPauseButton = 4;
const int shuffleButton = 3;
const byte volumePot = A0;
int prevVolume;
byte volumeLevel = 0; //variable for holding volume level
boolean isPlaying = false;
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
SoftwareSerial mySoftwareSerial(5, 6); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);
//*****************************************************************************************//
void setup() {
Serial.begin(115200); // Initialize serial communications with the PC, COMMENT OUT IF IT FAILS TO PLAY WHEN DISCONNECTED FROM PC
mySoftwareSerial.begin(9600);
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
pinMode(playPauseButton, INPUT_PULLUP);
pinMode(shuffleButton, INPUT_PULLUP);
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
if (!myDFPlayer.begin(mySoftwareSerial)) { //Use softwareSerial to communicate with mp3.
Serial.println(F("Unable to begin:"));
Serial.println(F("1.Please recheck the connection!"));
Serial.println(F("2.Please insert the SD card!"));
}
Serial.println(F("DFPlayer Mini online. Place card on reader to play a specific song"));
//myDFPlayer.volume(15); //Set volume value. From 0 to 30
volumeLevel = map(analogRead(volumePot), 0, 1023, 0, 30); //scale the pot value and volume level
myDFPlayer.volume(volumeLevel);
prevVolume = volumeLevel;
//----Set different EQ----
myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
// myDFPlayer.EQ(DFPLAYER_EQ_POP);
// myDFPlayer.EQ(DFPLAYER_EQ_ROCK);
// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ);
// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC);
// myDFPlayer.EQ(DFPLAYER_EQ_BASS);
}
//*****************************************************************************************//
void loop() {
volumeLevel = map(analogRead(volumePot), 0, 1023, 0, 30); //scale the pot value and volume level
if (prevVolume != volumeLevel){
myDFPlayer.volume(volumeLevel);
}
prevVolume = volumeLevel;
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
//some variables we need
byte block;
byte len;
MFRC522::StatusCode status;
if (digitalRead(playPauseButton) == LOW) {
if (isPlaying) {
myDFPlayer.pause();
isPlaying = false;
Serial.println("Paused..");
}
else {
isPlaying = true;
myDFPlayer.start();
Serial.println("Playing..");
}
delay(500);
}
if (digitalRead(shuffleButton) == LOW) {
myDFPlayer.next();
Serial.println("next Play");
isPlaying = true;
delay(1000);
}
//-------------------------------------------
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( mfrc522.PICC_IsNewCardPresent()) {
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
Serial.println(F("**Card Detected:**"));
//-------------------------------------------
mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid)); //dump some details about the card
//mfrc522.PICC_DumpToSerial(&(mfrc522.uid)); //uncomment this to see all blocks in hex
//-------------------------------------------
Serial.print(F("Number: "));
//---------------------------------------- GET NUMBER AND PLAY THE SONG
byte buffer2[18];
block = 1;
len = 18;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid)); //line 834
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Authentication failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
status = mfrc522.MIFARE_Read(block, buffer2, &len);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Reading failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
//PRINT NUMBER
String number = "";
for (uint8_t i = 0; i < 16; i++)
{
number += (char)buffer2[i];
}
number.trim();
Serial.print(number);
//PLAY SONG
if (number.toInt()>79){
myDFPlayer.playFolder(80, number.toInt());
isPlaying = true;
delay(1000);
}
else {
myDFPlayer.playFolder(number.toInt(), 1);
isPlaying = true;
delay(1000);
}
//----------------------------------------
Serial.println(F("\n**End Reading**\n"));
delay(1000); //change value if you want to read cards faster
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
}
//*****************************************************************************************//
I have mentioned above a range of things I have tried, nothing seems to work. I am a beginner so I am not sure what there is left that could be the problem!
I am working on a project with PIC16F877 (using MPLABX). I use RB0 pin external interrupt and RB4 pin portb interrupt to detect zero cross detection. I did everything correct, in proteus simulation everything was okey. Then I set up the circuit on breadboard, the LCD wasnt displaying the numbers (just the white dots). I thought the problem is the RB0 and PORTB interrupt. I wrote a simple code just includeshe PORTB interrupt and LCD and simulated. Everything is okey until the interrupt occures, when interrupt comes the code stops. I am new to PIC, this is the code I wrote:
/*
* File: lcd_deneme_16f877a.c
* Author: BATUHAN
*
* Created on 28 Aral?k 2022 Çar?amba, 13:52
*/
#include <xc.h>
#include <stdio.h>
#include <stdint.h>
#pragma config FOSC = XT // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = ON // Data EEPROM Memory Code Protection bit (Data EEPROM code-protected)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = ON // Flash Program Memory Code Protection bit (All program memory code-protected)
#define _XTAL_FREQ 4000000
void __interrupt() interrpt()
{
if(INTF)
{
uint8_t dummy = PORTB; // Read PORTB to end mismatch condition
INTF=0;
RD0=RD0^1;
}
if(RBIF==1 && RB4==1)
{
uint8_t dummy = PORTB; // Read PORTB to end mismatch condition
RBIF=0;
RD0=RD0^1;
}
}
void main(void)
{
TRISD=0X00;
PORTD=0X00;
TRISB=0b00010001;
PORTB=0X00;
INTCON=0b11011000; // GIE PEIE TMR0IE INTE RBIE TMR0IF INTF RBIF
OPTION_REGbits.nRBPU = 1;
INTEDG=1;
int V=0;
while(1)
{
V++;
__delay_ms(200);
}
return;
}
I tried the PORTB and RB0 interrupts separately and the problem still occurs.
What could be the problem. Thanks in advance
This is because your program stucks in interrupt routine due to the lack of proper handling of interrupts. You don't seem to handle the INT interrupt at all. For RB interrupt-on-change (IOC), you have to handle it sort of a little different and end the mismatch condition before clearing the flag. According to the PIC16F877A Datasheet this how the IOC works and must be handled:
Four of the PORTB pins, RB7:RB4, have an interrupt-on-change feature. Only pins configured as inputs can cause this interrupt to occur (i.e., any RB7:RB4 pin configured as an output is excluded from the interrupt-on-change comparison). The input pins (of RB7:RB4)are compared with the old value latched on the last read of PORTB. The “mismatch” outputs of RB7:RB4
are OR’ed together to generate the RB port change interrupt with flag bit RBIF (INTCON<0>). This interrupt can wake the device from Sleep. The user, in the Interrupt Service Routine, can clear the interrupt in the following manner:
a) Any read or write of PORTB. This will end the mismatch condition.
b) Clear flag bit RBIF.
A mismatch condition will continue to set flag bit RBIF. Reading PORTB will end the mismatch condition and allow flag bit RBIF to be cleared.
So your interrupt service code should look like the following:
void __interrupt() interrpt()
{
if(RBIF && RB4)
{
volatile uint8_t dummy = PORTB; // Read PORTB to end mismatch condition
RBIF=0;
RD1=RD1^1;
}
else if(INTIF) {
INTIF = 0;
RD0 = !RD0; // Toggle D0 for INT interrupt
}
}
A friendly reminder
The proteus simulation is ok for some cases. However the simulation runs in ideal conditions. That's why you may not get the same expected behaviour in the real world conditions compared to proteus' ideal simulation conditions.
void __interrupt() interrpt()
{
if(RBIF)
{
PORTB; // Read PORTB to end the mismatch condition
RBIF=0;
if(RB4)
RD1=RD1^1;
}
else if(INTF) {
INTF = 0;
RD0 = !RD0; // Toggle D0 for INT interrupt
}
}
I'm currently trying to put together a datalogger with an OLED screen and am having issues when adding the SD library to the script. I've seen that others have gotten error messages when combining Oled and SD cards that is related to RAM. Though in my case, the code runs, there is no error message, but the screen doesn't display anything. The code below shows the "OLED code" where the Oled display wouldn't show anything when I added the "#include <SD.h>". Also, since I quite new to this, some constructive criticism of the code itself is also welcome
Thanks!
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "Adafruit_MCP9808.h"
#include <Adafruit_BME280.h>
Adafruit_BME280 bme; // use I2C interface
Adafruit_Sensor *bme_temp = bme.getTemperatureSensor();
Adafruit_Sensor *bme_pressure = bme.getPressureSensor();
Adafruit_Sensor *bme_humidity = bme.getHumiditySensor();
//oled definitions
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Create the MCP9808 temperature sensor object
Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();
void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // Address 0x3D for 128x64
// Clear the buffer
display.display();
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.setTextColor(WHITE);
while (!Serial);
Serial.println("Loading");
if (!tempsensor.begin(0x18)) {
Serial.println("Couldn't find MCP9808! Check your connections and verify the address is correct.");
while (1);
}
Serial.println(F("Found MCP9808!"));
tempsensor.setResolution(3); // sets the resolution mode of reading, the modes are defined in the table bellow:
// Mode Resolution SampleTime
// 0 0.5°C 30 ms
// 1 0.25°C 65 ms
// 2 0.125°C 130 ms
// 3 0.0625°C 250 ms
if (!bme.begin()) {
Serial.println(F("Could not find a valid BME280 sensor, check wiring!"));
while (1) delay(10);
}
bme_temp->printSensorDetails();
bme_pressure->printSensorDetails();
bme_humidity->printSensorDetails();
}
void loop() {
float temp = bme.readTemperature(); // get temperature in degree Celsius
float humi = bme.readHumidity(); // get humidity in rH%
float pres = bme.readPressure(); // get pressure in Pa
tempsensor.wake();
//Serial.println (tempsensor.getResolution());
float c = tempsensor.readTempC();
float f = tempsensor.readTempF();
//float sensor=analogRead(A4);
display.setCursor(0, 0);
display.print(F("Temp_1: "));
display.print(c,2);display.println(" \tC ");
display.println("");
display.print(F("Temp_2: "));
display.print(temp,2);display.println(" \tC ");
display.println("");
display.print(F("Humidity: "));
display.print(humi,2);display.println(" %RH ");
display.println("");
display.print(F("Pressure: "));
display.print(pres/100,2);display.println(" kPa ");
display.display();
delay(1000);
display.clearDisplay();
Its just memory problem. I fix it by decrease the resolution only for usage area.. Its not the best solution however good enough for me
This was apparently a memory issue.
I've now connected an Arduino Mega instead of a Nano, and the code ran nicely. I've also added the remaining piece of code that was necessary to log the sensor readings.
According to what I've read on other forums, the SD and SPI libraries take up quite a lot of memory.
I made a nice code which generates fast PWM with 50% duty cycle and I can change the frequency with a potentiometer. It outputs straight and inverted channels with some dead time. I am using Arduino Micro aka ATmega32U4. The code is actually "Atmel" code. Code is working fine until I power Arduino Micro off and then on again.
I have programmed the code and registers so that the frequency is changeable from 10kHz to 100kHz. But after power on/off the frequency changes from 5kHz to 50kHz. After this has happened I have to program the board again using Arduino IDE, to make it work correctly. Again after power on/off it has changed. I am quite sure that one of the registers is overwritten by the "Arduino hardware abstraction layer" or however we should name it. I have not yet read out all the registers so I do not know which one is overwritten. I guess it's the prescaler.
How do I prevent this from happening? Should I write the register contents somewhere else? Or should I write it few times to be sure?
Why or how this is happening anyway?
Here's the code:
#define OSC1 5
#define OSC2 13
uint8_t read_reg1;
uint8_t read_reg2;
int pot, freq;
void setup() {
pinMode(OSC1, OUTPUT);
pinMode(OSC2, OUTPUT);
Serial.begin(9600);
cli(); // disable global interrupts
TCCR4A=0; // clear register
TCCR4B=0x06; // configure prescaler to 64 (CK = CLK / 64 = 1.5 MHz)
TCCR4C=0;
TCCR4D=0; // select Fast PWM operation (0 << WGM41)|(0 << WGM40)
PLLFRQ=(PLLFRQ&0xCF)|0x30; // select clock source and frequency
OCR4C=150; // select PWM frequency
OCR4A=150/2; // set duty cycle
DT4 = 0x55; // set dead times. DT = (1 / 48Mhz) * 0...15
// enable interrupt on timer4 overflow
TIMSK4|=(1 << TOIE4);
// This register write has to be after others. Otherwise the PWM generation will not work. I do not know why.
TCCR4A=0x42; // COM4A1..0 = 01, OC4A and !OC4A connected. PWM4A = 1 (activate channel A PWM output)
sei(); // enable global interrupts
}
void loop() {
//cli();
pot = analogRead(A0);
freq = map(pot, 0, 1023, 14, 166);
//sei();
/*
Serial.print("Pot value: ");
Serial.print(pot);
Serial.print("\tFreq value: ");
Serial.println(1500000/freq);
*/
}
ISR(TIMER4_OVF_vect){
OCR4C = freq;
OCR4A = freq / 2;
}
I am not sure exactly why you got different behavior right after programming, but the bootloader that the Arduino Micro uses (Caterina) does not perform a full reset after it runs, so changes that the bootloader made to the AVR's registers are often visible to the user's sketch.
I was able to fix the problem by removing the line that modifies PLLFRQ. Here is a simplified version of your code that always produces 3.31 kHz PWM:
void setup()
{
pinMode(5, OUTPUT);
pinMode(13, OUTPUT);
TCCR4A = 0;
TCCR4B = 0x06; // configure prescaler to 64 (CK = CLK / 64 = 1.5 MHz)
TCCR4C = 0;
TCCR4D = 0; // select Fast PWM operation (0 << WGM41)|(0 << WGM40)
OCR4C = 150; // select PWM frequency
OCR4A = 150 / 2; // set duty cycle
DT4 = 0x55; // set dead times. DT = (1 / 48Mhz) * 0...15
// This register write has to be after others.
// Otherwise the PWM generation will not work. I do not know why.
// COM4A1..0 = 01, OC4A and !OC4A connected.
// PWM4A = 1 (activate channel A PWM output)
TCCR4A = 0x42;
}
void loop()
{
}
It's not a great idea to mess with the PLL postscaler since it will probably affect every other Arduino library that uses timers, including the USB stack.
I'm writing a simple program for an Arduino that will take the input of 2 buttons and output simulated keys for 2 different functions to use in Clone Hero.
Arduino editor (both online and local versions) spit out
'Keyboard' was not declared in this scope
The offline editor asks if Keyboard.h is included... Which it obviously is.
Any ideas why?
// Keyboard - Version: Latest
#include <Keyboard.h>
//btnWhammy is the button to replace whammy bar function
//btnSP is the button to replace star power activation
//Set Clone Hero to register j for whammy and k for star power
//declaring constant integers for the pins on the Arduino
const int btnWhammy = 2;
const int btnSP = 13;
//Declaring integers for the state of the button press
int btnWhammyState = 0;
int btnSPState = 0;
void setup() {
//Initialisation of the pins as inputs
pinMode(btnWhammy, INPUT);
pinMode(btnSP, INPUT);
}
void loop() {
//Setting the button states to the read of the digital pin (LOW is off, HIGH is on)
btnWhammyState = digitalRead(btnWhammy);
btnSPState = digitalRead(btnSP);
//If the whammy button is pressed, send 'j' to the keyboard, wait 100ms then release all keys
if (btnWhammyState == HIGH) {
Keyboard.press('j');
delay(100);
Keyboard.releaseAll();
}
//If the Star Power button is pressed, send 'k' to the keyboard, wait 100ms then release all keys
if (btnSPState == HIGH) {
Keyboard.press('k');
delay(100);
Keyboard.releaseAll();
}
}
This is a classic mistake -- you are probably compiling for a non-Leonardo board, like a Uno. The Keyboard.h library is not included because it is not present for the board you are compiling with.
I took your code and compiled it for Leonardo -- no issues. For Uno, I get the same error as you...
keyboard key was not declared in this scope i found a very simple and working trick of this problem just go to your main file where you declare all other keys that you are facing not declare
#include <DigiKeyboard.h>
#define KEY_UP_ARROW 0x52
#define KEY_DOWN_ARROW 0x51
#define KEY_LEFT_ARROW 0x50
#define KEY_RIGHT_ARROW 0x4F
#define KEY_TAB 0x2B