Hello all,
Newbie (to the forum) here. Butterfingers is the moniker, probably reflecting my typing skills. ![]()
I have an Uno R3 with the ATmega328P chip and am having (sometimes frustrating) fun learning about micro-controllers.
I developed a project where (simplified) the micro-controller polls the analog inputs for change from the previous polling. If a change is detected a portion of related code is executed. All 6 analog inputs are used as are all 14 digital outputs.
I bread-boarded the micro-controller for portability and, as knowledge grew, eventually found more inputs (and outputs) were required. Multiplexing would not work for the analog inputs. A second ATmega328 was added and, after wiring for I2C (having moved some analog inputs to the second micro-controller). I hacked and installed the Master / Slave examples found in the learning section. I called the Master 100 and the Slave 101. Everything worked as expected.
The problem is, I need to run my code between the micro-controllers. Everything seemed to need Hex numbers or binary registries. Wow! I downloaded the 660 page datasheet for the ATmega328 and spent some considerable time looking for, among other things, A0 analog input.
I found the Hex address for A0 == 0x08(0x28) == (PortC bit 0). I hacked the code and established a form of communication that required the Master to read the slave (theoretically) and display the results on the Serial Monitor. Unfortunately, the results were 14 (followed with no spaces) by 255 255 255 (eight times) no matter what setting of the pot. That didn't make a lot of sense to me. Obviously, I'm doing something wrong. So, I was hoping for a different approach. Perhaps one that didn't involve directly accessing the registries?
I have so many questions and the butterfingers are blathering. My apologies. What I would like to do is:
1/ Master U100: polls it's own analog inputs (A0 - A3), if it detects change processes code. It then needs to poll the analog inputs on U101. When it comes to polling the analog inputs on the Slave U101, I would like it to ask the slave, "What is the value of A0?" Can I do that the same way in the learning examples for reading an analog input?
i.e.
Master: U100
#include <wire.h>
void setup() {
wire.begin(100); // establishes connection to I2C with identity 100 which may be used
//in future if Master becomes the Slave.
}
void loop() {
Wire.requestFrom(101) // asks Slave 101
while (Wire.available()) { // slave may send less than requested
firstPotval = Wire.read(A0); // receive the value read in U101-A0
}
}
2/ The Slave would then read U101-A0 and return the value.
Slave U101
#include <Wire.h>
void setup() {
Wire.begin(101); // join i2c bus with address 101
Wire.onRequest(requestEvent); // register event // I'm not sure I understand this part.
// can "requestEvent" be renamed to something like "readfirstPot"?
}
void loop() {
delay(100);
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() { // Can this be written // void readfirstPot() { ?
int firstPotval = analogRead(A0)/4;
Wire.write(firstPotval); // respond with A0 reading
// as expected by master
}
}
instead of writing a stream of bytes? I tried a code like this and got errors.
3/ The master would then determine if there is a change, if so, process the related code.
// With the exception of the new I2C part, This already works.
4/ However, now the Master needs to command the Slave to set the digital output on slave U101 pin 4 to HIGH.
e.g.
//Master (appropriately placed in the existing processing code)
//void setup() { // already established previously
Wire.begin(100); // join i2c bus (address for master)
//}
// void loop() { // already established previously
// previously written code that detected change in U101-A0 now executes the following
Wire.beginTransmission(101); // transmit to Slave 101
Wire.write(digitalWriteA(4, HIGH)); //writes digital pin 4 HIGH - this part will fail but
// I don't know how to write in the correct format.
// It's called digitalWriteA because there will be others
// and each needs to be distinctly labelled.
Wire.endTransmission(); // stop transmitting
delay(TimerA); // previously defined timer setting e.g. 300ms
//}
Slave U101:
// #include <Wire.h> already established earlier
//void setup() { // already established earlier
Wire.begin(101); // join i2c bus with address #101
Wire.onReceive(receiveEvent); // register event
}
void loop() {
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(digitalWriteA) {
digitalWrite(4, HIGH); // Turns on the LED on pin 4
}
I know the above code likely will not work. The problem is there is not many examples to draw from.
Can anyone help me re-write the above so that I can use the basic principles in all the other stuff I need to write (including a, soon to be added, digital display on U101, and various analog inputs / digital outputs)?
Thank you for reading this tome.
Best regards,
Butterfingers