Hey there!
I'm currently working on the following project:
Teensy 3.2 and ATtiny85 (programmed via Arduino ISP) are connected to an FRAM chip (http://www.fujitsu.com/us/Images/MB85RC256V-DS501-00017-3v0-E.pdf) via I2C.
ATtiny is reading an analog sensor and writes the value to the FRAM. Then the Teensy (which is supposed to work as the "main microcontroller" when everything works) is told that it's his turn and reads out the just written sensor value from the FRAM. The ATtiny always saves the current FRAM memory address in the first memory address. So when Teensy is told to read, it reads out the first address to know where the newest sensor value is saved in the FRAM and then reads out that value at the current address.
For testing, I use the Serial Monitor with the Teensy to print the values (sampled with with 1 Hz) it read from the FRAM.
I began with 2 Teensies which worked perfectly. When I switched to the ATtiny (8 MHz) using the TinyWireS library it became buggy:
The Teensy is still reading a value every second, but the it's always the same value. Even when I connect the analog input of the ATtiny to GND or any other potential the Teensy is always reading the same value.
I noticed that when I switch off the ATtiny just for a second, the correct value is printed on the monitor. But again, when I change the analog input the read-out value won't change!
That's why I think the ATtiny is causing the trouble. It either has trouble with:
-analog reading of the value
-saving the current address at the first address of the FRAM
-saving the current analog reading
Here's the code of ATtiny:
And here for the Teensy:
Any ideas on how to solve that?
Best regards,
Julian
I'm currently working on the following project:
Teensy 3.2 and ATtiny85 (programmed via Arduino ISP) are connected to an FRAM chip (http://www.fujitsu.com/us/Images/MB85RC256V-DS501-00017-3v0-E.pdf) via I2C.
ATtiny is reading an analog sensor and writes the value to the FRAM. Then the Teensy (which is supposed to work as the "main microcontroller" when everything works) is told that it's his turn and reads out the just written sensor value from the FRAM. The ATtiny always saves the current FRAM memory address in the first memory address. So when Teensy is told to read, it reads out the first address to know where the newest sensor value is saved in the FRAM and then reads out that value at the current address.
For testing, I use the Serial Monitor with the Teensy to print the values (sampled with with 1 Hz) it read from the FRAM.
I began with 2 Teensies which worked perfectly. When I switched to the ATtiny (8 MHz) using the TinyWireS library it became buggy:
The Teensy is still reading a value every second, but the it's always the same value. Even when I connect the analog input of the ATtiny to GND or any other potential the Teensy is always reading the same value.
I noticed that when I switch off the ATtiny just for a second, the correct value is printed on the monitor. But again, when I change the analog input the read-out value won't change!
That's why I think the ATtiny is causing the trouble. It either has trouble with:
-analog reading of the value
-saving the current address at the first address of the FRAM
-saving the current analog reading
Here's the code of ATtiny:
Code:
/*To-Do:
*/
#include <TinyWireM.h>
#define EEPROM_ADR 0x50
#define EEPROM_SIZE 32000
#define a_count 1 //Number of sensors, maximum is 3
#if (a_count == 1)
#define MAX_ADDR 32000
#elif (a_count == 2)
#define MAX_ADDR 32000
#elif (a_count == 3)
#define MAX_ADDR 31998
#else
#error "a_count maximum is 3"
#endif
/////////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Constants & Variables //////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
uint32_t current_addr = 1;
uint8_t counter = 0;
const uint32_t sample_int = 1000000; //microseconds
uint32_t previous_us = 0;
uint16_t a_data[a_count]; //Buffer to save analog read
uint8_t WakePin = 1;
uint8_t sample_pin = A3;
/*
struct analog_data {
uint16_t data[a_count];
// byte high_b[a_count];
// byte low_b[a_count];
} a_data;
*/
const uint8_t addr_step = sizeof(a_data);
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// Setup ////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
void setup() {
delay(100);
TinyWireM.begin();
pinMode(WakePin, OUTPUT);
digitalWrite(WakePin, LOW);
delay(100); // to make sure that T3.2 is in loop() and waiting
}
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// Loop ////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
void loop() {
if (digitalRead(WakePin) == HIGH) { //WakePin set LOW, just if it is HIGH
digitalWrite(WakePin, LOW);
}
uint32_t current_us = micros();
if (current_us - previous_us >= sample_int ) { //sample-routine
previous_us = current_us;
sample();
writeEEPROM_ADDR(current_addr); //write the current address to the first memory address
writeEEPROMPage(current_addr, a_data); //write the data at the current address
current_addr += addr_step;
if (current_addr >= MAX_ADDR) { //prevent overflow of address
current_addr = 1;
}
digitalWrite(WakePin, HIGH); // activate Teensy
delay(1);
}
}
/////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////// Functions ////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
void writeEEPROMPage(uint32_t eeAddress, uint16_t a_data[])
{
TinyWireM.beginTransmission(EEPROM_ADR);
TinyWireM.write((int)(eeAddress >> 8)); // MSB
TinyWireM.write((int)(eeAddress & 0xFF)); // LSB
for (uint8_t i = 0; i < sizeof(a_data); i++) {
byte high = highByte(a_data[i]);
byte low = lowByte(a_data[i]);
TinyWireM.write(high); //Write the data
TinyWireM.write(low);
}
TinyWireM.endTransmission(); //Send stop condition
}
/////////////////////////////////////////////////////////////////////////////////////
void writeEEPROM_ADDR(uint32_t eeAddress)
{
TinyWireM.beginTransmission(EEPROM_ADR);
TinyWireM.write((int)(0x00)); // MSB
TinyWireM.write((int)(0x00)); // LSB
TinyWireM.write((int)(eeAddress >> 8)); // MSB
TinyWireM.write((int)(eeAddress & 0xFF)); // LSB
TinyWireM.endTransmission(); //Send stop condition
}
/////////////////////////////////////////////////////////////////////////////////////
void sample() { //analogRead, loop just runs once for testing
for (uint8_t i = 0; i < a_count; i++) {
a_data[i] = analogRead(sample_pin);
}
}
/////////////////////////////////////////////////////////////////////////////////////
void readEEPROM(uint32_t eeaddress, uint16_t fram_array[])
{
TinyWireM.beginTransmission(EEPROM_ADR);
TinyWireM.write((int)(eeaddress >> 8)); // MSB
TinyWireM.write((int)(eeaddress & 0xFF)); // LSB
TinyWireM.endTransmission();
TinyWireM.requestFrom(EEPROM_ADR, (sizeof(a_data)));
byte high = 0xFF;
byte low = 0xFF;
uint8_t i = 0;
while (TinyWireM.available()) {
high = TinyWireM.read();
low = TinyWireM.read();
fram_array[i] = ((unsigned int)high << 8 ) + low;
i++;
}
}
/////////////////////////////////////////////////////////////////////////////////////
And here for the Teensy:
Code:
/*To-Do:
*/
#include <Wire.h>
#define EEPROM_ADR 0x50
#define EEPROM_SIZE 32000
#define a_count 1 //must be the same on ATtiny
#if (a_count == 1)
#define MAX_ADDR 32000
#elif (a_count == 2)
#define MAX_ADDR 32000
#elif (a_count == 3)
#define MAX_ADDR 31998
#else
#error "a_count maximum is 3"
#endif
/////////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Constants & Variables //////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
uint32_t current_addr = 0;
uint8_t counter = 0;
const uint32_t sample_int = 1000000; //microseconds
uint32_t previous_us = 0;
uint16_t a_data[a_count]; //dummy for buffer size, could use fram_read[] too...
uint16_t fram_read[a_count]; //buffer for the values out of the FRAM
uint8_t WakePin = 10;
volatile bool read_allowed = false;
/*
struct analog_data {
uint16_t data[a_count];
// byte high_b[a_count];
// byte low_b[a_count];
} a_data;
*/
const uint8_t addr_step = sizeof(a_data);
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// Setup ////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
void setup() {
Wire.begin();
// Wire.setClock(100000);
attachInterrupt(digitalPinToInterrupt(WakePin), wake_up, RISING);
read_allowed = false;
}
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// Loop ////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
void loop() {
while (!read_allowed) {
} // wait for Attiny
current_addr = readEEPROM_ADDR(); //reads the current address at the first memory address of the FRAM
readEEPROM(current_addr, fram_read); //reads the values at the current address
for (uint8_t i = 0; i < a_count; i++) {
Serial.print(fram_read[i]);
Serial.print(" ");
}
Serial.println();
read_allowed = false;
}
/////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////// Functions ////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
void writeEEPROMPage(uint32_t eeAddress, uint16_t a_data[])
{
Wire.beginTransmission(EEPROM_ADR);
Wire.write((int)(eeAddress >> 8)); // MSB
Wire.write((int)(eeAddress & 0xFF)); // LSB
for (uint8_t i = 0; i < sizeof(a_data); i++) {
byte high = highByte(a_data[i]);
byte low = lowByte(a_data[i]);
Wire.write(high); //Write the data
Wire.write(low);
}
Wire.endTransmission(); //Send stop condition
}
/////////////////////////////////////////////////////////////////////////////////////
void sample() { //analogRead
for (uint8_t i = 0; i < a_count; i++) {
a_data[i] = analogRead(A0);
}
}
/////////////////////////////////////////////////////////////////////////////////////
void readEEPROM(uint32_t eeaddress, uint16_t fram_array[])
{
Wire.beginTransmission(EEPROM_ADR);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(EEPROM_ADR, (sizeof(a_data)));
byte high = 0xFF;
byte low = 0xFF;
uint8_t i = 0;
while (Wire.available()) {
high = Wire.read();
low = Wire.read();
fram_array[i] = ((unsigned int)high << 8 ) + low;
i++;
}
}
/////////////////////////////////////////////////////////////////////////////////////
uint32_t readEEPROM_ADDR()
{
Wire.beginTransmission(EEPROM_ADR);
Wire.write((int)(0x00)); // MSB
Wire.write((int)(0x00)); // LSB
Wire.endTransmission();
Wire.requestFrom(EEPROM_ADR, (sizeof(a_data)));
byte high = 0xFF;
byte low = 0xFF;
uint32_t addr = 0;
while (Wire.available()) {
high = Wire.read();
low = Wire.read();
addr = ((unsigned int)high << 8 ) + low;
}
return addr;
}
/////////////////////////////////////////////////////////////////////////////////////
void wake_up() { //ISR
read_allowed = true;
}
/////////////////////////////////////////////////////////////////////////////////////
Any ideas on how to solve that?
Best regards,
Julian