How to read the reset vector on an ATMEGA328 - arduino

I have several ATMEGA328 based custom boards: I recently found that the standard Arduino bootloader does not handle watchdog timeouts correctly (it keeps resetting, so the device is effectively bricked until the next power cycle) so I am switching to the Optiboot bootloader.
I want to add something to my app that tells me whether the bootloader is Arduino or Optiboot. As Optiboot is a lot smaller, the reset vector is different, so printing that out would be a good indication.
Serial.println (pgm_read_word_near(0), HEX);
The above line of code prints out 940C, and I was expecting something like 7E00. How can I print out the address from the reset vector?

The actual address of the start of the boot flash section is determined by the BOOTSZ fuses.
This reads the size of the bootloader for classic ATmega:
uint32_t bootloaderSize;
cli();
uint8_t highBits = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
sei();
if (!(highBits & bit(FUSE_BOOTRST))) {
uint8_t v = (highBits & ((~FUSE_BOOTSZ1 ) + (~FUSE_BOOTSZ0 )));
bootloaderSize = MIN_BOOTSZ << ((v >> 1) ^ 3);
}
use #include <avr/boot.h>

Related

PIC 32 baud rate

i have a PIC32MX460F512L. I am setting up a UART communication with raspberry Pi 3. And i made also some tests with mi PC Windows serial terminal (Putty, Teraterm etc.). I am having stucking problems, because the raspberry sends and receives only rubbish. Then i tested it with putty on Windows and i noticed strange things. For example the uart baud rate on the board is set as 9600, and to send and receive data on windows i have to set putty's baud rate to 130 !! Then i had a look to my PCLK settings on pic and it seems like everything is correct since there is an external clk oscillator of 8MHz. I post the code below .
PIC CODE:
#define GetSystemClock() (80000000ul) // Hz
#define GetInstructionClock() (GetSystemClock()/1)
#define GetPeripheralClock() (GetInstructionClock()/1) //
long Baud_Rate;
Baud_Rate = 9600;
TRISFbits.TRISF8 = 0; // Set UART1TX like output
TRISFbits.TRISF2 = 1; // Set UART1RX like input
U1MODE = 0x00008000;
U1STA = 0x00001400; // RXEN set, TXEN set
U1BRG = ((USART_Clock_Source)/(Baud_Rate/16))-1;
May it be a fault on the external oscillator or maybe is there an error on the baud rate calculation? I cannot understand.
Here is an error:
U1BRG = ((USART_Clock_Source)/(Baud_Rate/16))-1;
it should be:
U1BRG = ((USART_Clock_Source)/(Baud_Rate*16))-1;
And this:
#define GetSystemClock() (80000000ul) // Hz
should be
#define GetSystemClock() (8000000ul) // Hz
In this calculation is 8 MHz the instruction frequency not the clock frequency. The instruction frequency is half of the clock.

ESP8266 "ovf" when doing small double maths

I'm using a Wemos D1 based on the ESP8266 wifi chip with the Arduino C framework to do some simple small math.
As far as I can gather, double precision is available so I'm using it - with a maximum of something like 1.8*10^103.
But I'm getting an ovf when I try to calculate a number around 5*10^8.
Any ideas please?
void setup(){
Serial.begin(9600);
while(!Serial);
Serial.println("Hit any key to start math");
double te = 6800;
double res = te * te;
Serial.println(res);
te = 68000;
res = te * te;
Serial.println(res);
te = 680000;
res = te * te;
Serial.println(res);
}
void loop(){
}
Prints
46240000.00
ovf
ovf
Arduino does supports 4-byte double data type. and your code is indeed produced a valid double value that is not overflow (ovf).
The problem that you see has to do with the way Arduino implement Serial.print() function which is almost like a half-cooked hack to support floating-point and is not as reliable as vprintf() that is available in avr-libc. You can see the source code here which print ovf for anything bigger than 4294967040.0 or smaller than -4294967040.0. I thought that ESP8266 Arduino Core has fixed this instead of inheriting the ugly implementation of Arduino Serial.print(), but apparently not.
Luckily the ESP8266 Arduino Core does have a Serial.printf() method that provide better floating point rendering. This code will shows that your number is indeed a valid number for double data type.
void setup(){
Serial.begin(9600);
while(!Serial);
double te = 68000;
double res = te * te;
Serial.println(res); //this will produce 'ovf'
Serial.printf("Result=%f\n", res); //this will produce correct 4624000000.000000
}
Please noted that Serial.printf() is ESP8266 specific implementation to support full floating point vprintf() in the standard library. It is not available for standard Arduino Boards.
For Arduino boards, there is a way to use sprintf() which inherits from vprintf() to print the correct floating point with some twist on linker options during code compilation process. I have a blog post Do you know Arduino - sprintf() and floating point talk about how to do that.

Serial.print() truncates data when reading with QSerialPort

I am trying to write a simple integer value from an Arduino Mega 2560 to a Qt Application. Baudrate is set to 9600 and Serial.read() works fine when I send data through an open port with serial->write(some_data); from Qt Application.
digitalWrite(SS, LOW);
if (Serial.available() == 2) {
response1 = SPI.transfer(Serial.read());
response2 = SPI.transfer(Serial.read());
}
digitalWrite(SS, HIGH);
The above code works fine. I read another by before and had to add delay(3) to make this work. Now I want to send back the response
Serial.print((response2 << 8 ) | (response1 & 0xFF));
But there are always truncated digits. I know from the logic analyzer that the response is e.g. 8193 so with QByteArray b = serial->readAll(); I get results like 8, 81, 819, and sometimes 8193. I.e.: always the last digits are truncated randomly. I assume that this is also a timing issue but I could not find a fix for this.
Just in case anyone facing the same issue: Changing the Baudrate from 9600 to 112500 fixed this.

Arduino Due output TIOA and TIOB without interrupts

I am an electrical student and want to use arduino due to generate pulses for driving MOSFETs. I am making a inverter and want to generate pulses. I have arduino due with me. My main aims are :
1) one software interrupt for sampling the next time period (this will be changing..). After three cycles I will analogRead() new value of time period and same continues .
2) During one time period,set by RC count of Timer channel TC0, I want to load RA0 and RB0 with appropriate counts to get output pulses with different duty ratios(depending on RA0 and RB0 values).
I wrote a program which gives software interrupts with TC3 which is working fine. i.e. I am able to load new values into RA0 and RB0 automatically for every new sampled value( every 3 cycles new values comes else same values will be loaded).
Now I also used TC0 (i used Olavi Kamppari's library) for stopping, loading new values and starting the timer.
when i checked PIO_PB25B_TIOA0 and PIO_PB27B_TIOB0 in the serial monitor i am getting 33554432,134217728 .
I am really confused.I expected a 1 and 0 output. I just want two pulses from TC0 without interrupt.I set the ACPA value to 3 (Toggle) and I enabled the clock to the timer as well.Still I am not getting the output.
So if possible please provide me a sample program that can output pulses from PB25 and PB27 (TIOA0 and TIOB0). Any help will be greatly appreciated.
Thanks for reading my question.
Thank you.
The following sketch outputs a 3 MHz signal on TIOA6 (Pin 5 from memory)
I am about to post a question regarding the same code - I want to get to 8 (and a little bit) MHz but have hit a conceptual brick wall!
Note that this is under development - the IRQ handler is not used - and the PMC_Enable_Periph should be referring to ID_TC6 (I believe) - then the IRQ handler can be placed in the dust bin of history!
void TC6_Handler()
{
TC_GetStatus(TC2, 0);
}
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq) {
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
TC_Configure(tc, channel,
TC_CMR_WAVE |
TC_CMR_WAVSEL_UP_RC |
TC_CMR_TCCLKS_TIMER_CLOCK1|
TC_CMR_ACPA_TOGGLE ); // RC compare TOGGLES TIOA)smiley-wink;
TC_SetRA(tc, channel, 1); //50% high, 50% low
TC_SetRC(tc, channel, 1);
PIO_Configure(PIOC,
PIO_PERIPH_B,
PIO_PC25B_TIOA6,
PIO_DEFAULT);
TC_Start(tc, channel);
}
void setup(){
startTimer(TC2, 0, TC6_IRQn);
}
void loop(){
}

Arduino's analogRead() returns junk when I print via serial

I'm making a clock with the Arduino, and I want to make a button to set the time.
So, just to test, I pluged a wire in the Analog Input pin 0 and wrote two lines of code to read the pin and print it via Serial, but all I get is junk.
valm = analogRead(0);
Serial.println(valm);
And what I get from the serial monitor is this:
?j?d?±µ?Ê??jDd?±µ???ºjRd?±µ???ºj?d?±µ?Ê??j?d?±µ?É?ªjRd?±µ???ÊjRd?±µ???Âj?d?±µ????j?d?±µ?É??j
Rd?±µ????j?d?±µ???ºj?d?±µ?É??jRd?±µ????j?d?±µ?Ê?ÊjDd?±µ???Âj?d?±µ????j?d?±µ?É??jRd?±µ????j?d
?±µ?É?ÂjRd?±µ???Êj?d?±µ???ªj?d?±µ?Ê?Êj$d?±µ???ÂjRd?±µ????j?d?±µ????jdd?±µ????jRd?±µ???Âj?d?±
µ?É?ÊjRd?±µ????j?d?±µ?Ò?Êj?d?±µ?É?ÂjRd?±µ????j?d?±µ????j?d?±µ?É??jRd?±µ???Âj?d?±µ???Êj?d?±µ?
??ªj?d?±µ???Êj?d?±µ???ÂjRd?±µ????j?d?±µ????j?d?±µ?É??jRd?±µ???Âj?d?±µ?Ò?Êj?d?±µ?É?ªj?d?±µ?É?
?jTd?±µ???Âj?d?±µ????j?d?±µ?É??jRd?±µ????j?d?±µ?É?ÂjRd?±µ???Êj?d?±µ?É?ªjRd?±µ???Êj?d?±µ???ºj
?d?±µ?È??jTd?±µ????jRd?±µ???ªj?d?±µ?È?ÂjTd?±µ?É?ÊjRd?±µ???ªj?d?±µ???Êj?d?±µ???ºj?d?±µ?É??jRd
?±µ???Êj?d?±µ???ªj?d?±µ?É?ÂjPd?±µ???Êj?d?±µ???ªj?d?±µ?Â?Êj?d?±µ?É?ºjRd?±µ????j?d?±µ?É??jRd?±
µ???ªj?d?±µ?Ê?Âj?d?±µ???ÊjRd?±µ???ªj?d?±µ?Ò?Êj?d?±µ???ºjRd?±µ????j?d?±µ???Êj?d?±µ?Ê?ªjdd?±µ?
??ÂjRd?±µ???Âj?d?±µ?É?ªjPd?±µ???Êj?d?±µ????j?d?±µ?É??jRd?±µ???Êj?d?±µ?É?ªjdd?±µ???ÂjRd?±µ???
Âj?d?±µ?É?ªjDd?±µ???Êj?d?±µ?Ê??j?d?±µ?É??jRd?±µ???ÊjRd?±µ???ªj?d?±µ?Ê?ÂjPd?±µ???Âj?d?±µ???ªj
?d?±µ?É?Êjdd?±µ?É??jRd?±µ????j?d?±µ?É?Êj$d?±µ???ªjRd?±µ???Âj?d?±µ?Â?ÂjTd?±µ???ªj?d?±µ???Êj?d
?±µ????jRd?±µ????j?d?±µ?É?ÊjTd?±µ???ªjRd?±µ???Âj?d?±µ???Âj?d?±µ?É?ªjRd?±µ???ÊjRd?±µ?Ò??jTd?±
µ????j?d?±µ???Êj
Why?
Edit:
I had set the digital pin 0 to output, and I thought maybe that was the problem so I went to the Arduino website and found the page Analog Input Pins.
So I tried to read from pin 14 which they say is the analog input pin 0, but I got the same output.
By the way, I'm trying to read from the analog only pins, not the one wich are also digital.
Try running this sample code found on the Arduino website. You shouldn't need to convert the variable valm or anything.
/*
Analog input
Reads an analog input on analog in 0, and prints the value out.
Created 24 March 2006
by Tom Igoe
*/
int analogValue = 0; // Variable to hold the analog value.
void setup() {
// open the serial port at 9600 bit/s:
Serial.begin(9600);
}
void loop() {
// Read the analog input on pin 0:
analogValue = analogRead(0);
// Print it out in many formats:
Serial.println(analogValue); // print as an ASCII-encoded decimal
Serial.println(analogValue, DEC); // print as an ASCII-encoded decimal
Serial.println(analogValue, HEX); // print as an ASCII-encoded hexadecimal
Serial.println(analogValue, OCT); // print as an ASCII-encoded octal
Serial.println(analogValue, BIN); // print as an ASCII-encoded binary
Serial.println(analogValue, BYTE); // print as a raw byte value
// Delay 10 milliseconds before the next reading:
delay(10);
}
If your output is still gibberish, there's something wrong with your serial terminal.
The problem Here is analog device you might connected are not # same ground potentials.
Example: If your powering on Arduino board using PC and sensor is powered on using other source , But You trying to read value from Arduino port, for this instant it gives above error. Try this power on arduino and sensor from Same power source and try to read data using Serial Port through DOcklight you will get Problem solved.
You need to set the baud rate in the serial monitor window (bottom right corner) to the same value that has been set in your code (e.g. Serial.begin(9600);).
From what your output looks like, it seems like you need to convert valm into a string, so that you can print the value numerically.
Also, is the wire you plugged into analog in floating? Because if it is, it'll just act like an antenna and grab random noise (though, might have a strong 60Hz component).

Resources