I'm trying to use the code below. After hours of trying to get this to work on a new Uno R4 I decided to give an older Uno board a try. With an older Uno board it works. With the R4 I get
Compilation error: util/atomic.h: No such file or directory
#include <util/atomic.h> // For the ATOMIC_BLOCK macro
#define ENCA 2 // YELLOW
#define ENCB 3 // WHITE
#define PWM 5
#define IN2 6
#define IN1 7
volatile int posi = 0; // specify posi as volatile: https://www.arduino.cc/reference/en/language/variables/variable-scope-qualifiers/volatile/
void setup() {
Serial.begin(9600);
pinMode(ENCA,INPUT);
pinMode(ENCB,INPUT);
attachInterrupt(digitalPinToInterrupt(ENCA),readEncoder,RISING);
pinMode(PWM,OUTPUT);
pinMode(IN1,OUTPUT);
pinMode(IN2,OUTPUT);
}
void loop() {
// Read the position in an atomic block to avoid a potential
// misread if the interrupt coincides with this code running
// see: https://www.arduino.cc/reference/en/language/variables/variable-scope-qualifiers/volatile/
int pos = 0;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
pos = posi;
}
setMotor(1, 25, PWM, IN1, IN2);
delay(200);
Serial.println(pos);
setMotor(-1, 25, PWM, IN1, IN2);
delay(200);
Serial.println(pos);
setMotor(0, 25, PWM, IN1, IN2);
delay(20);
Serial.println(pos);
}
void setMotor(int dir, int pwmVal, int pwm, int in1, int in2){
analogWrite(pwm,pwmVal);
if(dir == 1){
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
}
else if(dir == -1){
digitalWrite(in1,LOW);
digitalWrite(in2,HIGH);
}
else{
digitalWrite(in1,LOW);
digitalWrite(in2,LOW);
}
}
void readEncoder(){
int b = digitalRead(ENCB);
if(b > 0){
posi++;
}
else{
posi--;
}
}
From the first sentence on the product landing page:
The flexible Renesas Advanced (RA) 32-bit microcontrollers (MCUs) are industry-leading 32-bit MCUs with the Arm® Cortex®-M33, -M23 and -M4 processor cores and PSA certification.
It sounds to me like they're calling them Arm over at Renesas.
From a marking department that talks about this being a "Quantum leap" in computing power do you have any faith that it knows what it is talking about?
Maybe I should have said that it uses a R7FA4M1AB3CFL/ R7FA4M1AB3CNE processor then. That is the cut down 48 pin package that has many features that are inaccessible due to the lack of pins.
But what ever it is, it is not just an Arm processor.
No of course not. Nothing is JUST an "Arm processor", because that would be pretty useless. It's all about the peripherals. And the Renesas peripherals are different than the SAMD peripherals, and different than the ST peripherals. That doesn't mean much.
How are you defining "normal ARM code"? The biggest weirdness I see at the hardware level is that they have inserted their own Interrupt Controller that sits on top of the CM4 "NVIC", and maps the 174 sources to 32 ARM interrupts. (I don't know why. CM4 allows for many NVIC interrupts. Perhaps they want to maintain compatibility with CM0 chips as well? Or some other legacy chips?)
And then there's the software. I (sadly) do not expect a new chip with new peripherals to work with all of the libraries that were working on some subset of previous boards. With the "chaotic" state of Arduino libraries (some of which were written a long time ago by people who have long since gafiated from the Arduino world), it shouldn't be surprising.
There ARE oddities in the core implementation - the decision to work on top of the Renesas SDK ensures that (although the weirdest thing I've found is that the core uses one of the chip-specific timers instead of the ARM SysTick for the millisecond tick, and that seems excessively NIH-ish.)
#include <RadioHead.h>
#include <RHutil/atomic.h>
//#include <util/atomic.h> // For the ATOMIC_BLOCK macro
#define ENCA 2 // YELLOW
#define ENCB 3 // WHITE
#define IN2 5
#define IN1 6
volatile int posi = 0; // specify posi as volatile: https://www.arduino.cc/reference/en/language/variables/variable-scope-qualifiers/volatile/
long prevT = 0;
float eprev = 0;
float eintegral = 0;
void setup() {
Serial.begin(9600);
pinMode(ENCA,INPUT_PULLUP);
pinMode(ENCB,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCA),readEncoder,RISING);
pinMode(IN1,OUTPUT);
pinMode(IN2,OUTPUT);
}
void loop() {
// set target position
int target = 300;
//int target = 250*sin(prevT/1e6);
// PID constants
float kp = 4.0;
float kd = 0.0;
float ki = 0.0;
// time difference
long currT = micros();
float deltaT = ((float) (currT - prevT))/( 1.0e6 );
prevT = currT;
// Read the position in an atomic block to avoid a potential
// misread if the interrupt coincides with this code running
// see: https://www.arduino.cc/reference/en/language/variables/variable-scope-qualifiers/volatile/
int pos = 0;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
pos = posi;
}
// error
int e = pos - target;
// derivative
float dedt = (e-eprev)/(deltaT);
// integral
eintegral = eintegral + e*deltaT;
// control signal
float u = kp*e + kd*dedt + ki*eintegral;
// motor power
float pwr = fabs(u);
if( pwr > 255 ){
pwr = 255;
}
// motor direction
int dir = 1;
if(u<0){
dir = -1;
}
// signal the motor
if(abs(e) > 1){
setMotor(dir,pwr,IN1,IN2);
Serial.print(target);
Serial.print(" ");
Serial.print(pos);
Serial.print(" ");
Serial.print(pwr);
Serial.print(" ");
Serial.println();
}
else{
digitalWrite(IN1,LOW);
digitalWrite(IN2,LOW);
}
// store previous error
eprev = e;
}
void setMotor(int dir, int pwmVal, int in1, int in2){//variable pwm shouldn't be needed any longer
//analogWrite(pwm,pwmVal);
if(pwmVal < 6){
pwmVal = 6;
}
if(dir == 1){
analogWrite(in1,pwmVal);
digitalWrite(in2,LOW);
}
else if(dir == -1){
digitalWrite(in1,LOW);
analogWrite(in2,pwmVal);
}
else{
digitalWrite(in1,LOW);
digitalWrite(in2,LOW);
}
}
void readEncoder(){
int b = digitalRead(ENCB);
if(b > 0){
posi++;
}
else{
posi--;
}
}
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RHHardwareSPI.cpp: In member function 'virtual void RHHardwareSPI::begin()':
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RHHardwareSPI.cpp:137:57: error: invalid conversion from 'uint8_t {aka unsigned char}' to 'BitOrder' [-fpermissive]
_settings = SPISettings(frequency, bitOrder, dataMode);
^
In file included from C:\Users\travi\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.4\libraries\SPI/SPI.h:22:0,
from c:\Users\travi\Documents\Arduino\libraries\RadioHead/RadioHead.h:1517,
from c:\Users\travi\Documents\Arduino\libraries\RadioHead/RHGenericSPI.h:10,
from c:\Users\travi\Documents\Arduino\libraries\RadioHead/RHHardwareSPI.h:10,
from c:\Users\travi\Documents\Arduino\libraries\RadioHead\RHHardwareSPI.cpp:7:
C:\Users\travi\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.4\cores\arduino/api/HardwareSPI.h:47:3: note: initializing argument 2 of 'arduino::SPISettings::SPISettings(uint32_t, BitOrder, int)'
SPISettings(uint32_t clock, BitOrder bitOrder, int dataMode) {
^~~~~~~~~~~
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp: In member function 'void RH_ASK::timerSetup()':
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp:463:5: error: 'TCCR1A' was not declared in this scope
TCCR1A = 0; // Output Compare pins disconnected
^~~~~~
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp:464:5: error: 'TCCR1B' was not declared in this scope
TCCR1B = _BV(WGM12); // Turn on CTC mode
^~~~~~
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp:464:18: error: 'WGM12' was not declared in this scope
TCCR1B = _BV(WGM12); // Turn on CTC mode
^~~~~
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp:464:14: error: '_BV' was not declared in this scope
TCCR1B = _BV(WGM12); // Turn on CTC mode
^~~
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp:464:14: note: suggested alternative: '_B'
TCCR1B = _BV(WGM12); // Turn on CTC mode
^~~
_B
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp:471:5: error: 'OCR1A' was not declared in this scope
OCR1A = nticks;
^~~~~
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp:478:5: error: 'TIMSK' was not declared in this scope
TIMSK |= _BV(OCIE1A);
^~~~~
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp:478:18: error: 'OCIE1A' was not declared in this scope
TIMSK |= _BV(OCIE1A);
^~~~~~
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp: At global scope:
c:\Users\travi\Documents\Arduino\libraries\RadioHead\RH_ASK.cpp:798:4: error: expected constructor, destructor, or type conversion before '(' token
ISR(RH_ASK_TIMER_VECTOR)
^