Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help converting atmega32u4 #4

Open
NonaSuomy opened this issue Oct 28, 2022 · 6 comments
Open

Help converting atmega32u4 #4

NonaSuomy opened this issue Oct 28, 2022 · 6 comments

Comments

@NonaSuomy
Copy link

NonaSuomy commented Oct 28, 2022

Hi @thebradleysanders
I see you converted the code for the mega any idea how to convert it for the 32u4?

https://github.com/thebradleysanders/ESPHome-Arduino-Port-Expander/blob/main/arduino_port_expander.h#L34

How do you get the right binary values for the pins?

01 (INT.6/AIN0) PE6
02 UVcc
03 D
04 D+
05 UGnd
06 UCap
07 VBus
08 (SS/PCINT0) PB0
09 (PCINT1/SCLK) PB1
10 (PDI/PCINT2/MOSI) PB2
11 (PDO/PCINT3/MISO) PB3
12 (PCINT7/OC0A/OC1C/RTS) PB7
13 RESET
14 VCC
15 GND
16 XTAL2
17 XTAL1
*18 (OC0B/SCL/INT0) PD0
*19 (SDA/INT1) PD1
20 (RXD1/INT2) PD2
21 (TXD1/INT3) PD3
22 (XCK1/CTS) PD5
23 GND
24 AVCC
25 PD4 (ICP1/ADC8)
26 PD6 (T1/OC4D/ADC9)
27 PD7 (T0/OC4D/ADC10)
28 PB4 (PCINT4/ADC11)
29 PB5 (PCINT5/OC1A/OC4B/ADC12)
30 PB6 (PCINT6/OC1B/OC4B/ADC13)
31 PC6 (OC3A/OC4A)
32 PC7 (ICP3/CLK0/OC4A)
33 PE2 (HWB)
34 VCC
35 GND


Analog
32u4                         324p                                Not defined
36 PF7 (ADC7/TDI)   22 ADC7 
37 PF6 (ADC6/TDO) 19 ADC6 
38 PF5 (ADC5/TMS) 28 PC5 (ADC5/SCL/PCINT13)    26 PC3 (ADC3/PCINT11)
39 PF4 (ADC4/TCK)  27 PC4 (ADC4/SDA/PCINT12)   25 PC2 (ADC2/PCINT10)
40 PF1 (ADC1)          22 PC1 (ADC1/PCINT9)
41 PF0 (ADC0)          23 PC0 (ADC0/PCINT8)


42 AREF
43 GND
44 AVCC

Thank you for any help.

@thebradleysanders
Copy link
Owner

thebradleysanders commented Oct 28, 2022 via email

@thebradleysanders
Copy link
Owner

Better yet, it should work, the only thing that shouldn't is the analog pins, can you try and and let me know if the digital pins work? I don't have a board to test.

@NonaSuomy
Copy link
Author

NonaSuomy commented Oct 28, 2022

I have not tested the digital pins yet as I wanted to use the analog ones. Will have a look and report back. Seems they have 12 analog pins broken out on this board A0-A11. Currently A0 gives me a value in the 100’s with a 10k pot attached. A1 gives a value in the 10000’s for some reason (thought it was supposed to only be 0-1023) all the rest of the analog just show zero.

68CC263C-BD19-4B0D-A00B-59A26E967FE2
FA0EAC10-C2B2-4A25-A3B8-D220CDDD9462

https://medesign.seas.upenn.edu/index.php/Guides/MaEvArM-adc

@NonaSuomy
Copy link
Author

Is it possible to convert the analog pin defined part to use Arduino A0 etc internal pin definitions so these binary values wouldn't be required?

@NonaSuomy
Copy link
Author

NonaSuomy commented Oct 29, 2022

With the default code base:

GND                                     VCC +5V
00 B0  (00)                            F0 21 A00 (A1 Value:538 Idle: 96)
01 B1  (01)                            F1 20 A01 (A0 Value:32864 Idle: 96)
02 B2  (02)                            F4 19 A02 (?? Output 0)
03 B3  (03)                            F5 18 A03 (?? Output 0)
04 B7  (04)                            F6 17 A04 (?? Output 0)
24 E8  (?? No response)     (Interior)  AREF AF 
05 D0 (SCL)                           F7 16 A05 (?? Output 0)
06 D1 (SDA)                          B6 15 A06 (?? Output 0)
07 D2 (07)                             B5 14 A07 (?? Output 0)
08 D3 (08)                             B4 13 A08 (?? Output 0)
09 C6 (09)                             D7 12 A09 (?? Output 0)
10 C7 (10)                             D6 11 A10 (?? Output 0)
23 D3 (?? No response)        D4 22 A11 (?? Output 0)
+5V 
GND 
RST  

Stuff in brackets confirmed pins applied 2.64V with the 10K Pot to the analog pins. 7.09KOhm~

ttgo-poe-001.yaml (ESPHome)

# Define I2C device
i2c:
  id: i2c_component
  sda: 14
  scl: 16
  scan: true

# Define the port expander hub, here we define one with id 'expander1',
# but you can define many
custom_component:
  - id: expander1
    lambda: |-
      auto expander = new ArduinoPortExpander(i2c_component, 0x08, true);
      return {expander};
  - id: expander2
    lambda: |-
      auto expander = new ArduinoPortExpander(i2c_component, 0x09, true);
      return {expander};

# Define binary sensors, use the Arduino PIN number for digital pins.
binary_sensor:
  - platform: custom
    lambda: |-
      return {ape_binary_sensor(expander2, 0),
              ape_binary_sensor(expander2, 1),
              ape_binary_sensor(expander2, 2),
              ape_binary_sensor(expander2, 3),
              ape_binary_sensor(expander2, 4),
              ape_binary_sensor(expander2, 7),
              ape_binary_sensor(expander2, 8),
              ape_binary_sensor(expander2, 9),
              ape_binary_sensor(expander2, 10),
              ape_binary_sensor(expander2, 23),
              ape_binary_sensor(expander2, 24)
             };

    binary_sensors:
      - id: expander2_0
        name: Expander2 Digital 0
      - id: expander2_1
        name: Expander2 Digital 1
      - id: expander2_2
        name: Expander2 Digital 2
      - id: expander2_3
        name: Expander2 Digital 3
      - id: expander2_4
        name: Expander2 Digital 4
      - id: expander2_7
        name: Expander2 Digital 7
      - id: expander2_8
        name: Expander2 Digital 8
      - id: expander2_9
        name: Expander2 Digital 9
      - id: expander2_10
        name: Expander2 Digital 10
      - id: expander2_23
        name: Expander2 Digital 23
      - id: expander2_24
        name: Expander2 Digital 24

# Define analog sensors
sensor:
  - platform: custom
    lambda: |-
      return {ape_analog_input(expander2, 0),  // 0 = A0
              ape_analog_input(expander2, 1),  // 1 = A1
              ape_analog_input(expander2, 2),  // 2 = A2
              ape_analog_input(expander2, 3),  // 3 = A3
              ape_analog_input(expander2, 4),  // 4 = A4
              ape_analog_input(expander2, 5),  // 5 = A5
              ape_analog_input(expander2, 6),  // 6 = A6
              ape_analog_input(expander2, 7),  // 7 = A7
              ape_analog_input(expander2, 8),  // 8 = A8
              ape_analog_input(expander2, 9),  // 9 = A9
              ape_analog_input(expander2, 10),  // 10 = A10
              ape_analog_input(expander2, 11)  // 11 = A11
             };
    sensors:
      - name: Analog A0
        id: analog_a0
        filters:
          - throttle: 2s
      - name: Analog A1
        id: analog_a1
        filters:
          - throttle: 2s
      - name: Analog A2
        id: analog_a2
        filters:
          - throttle: 2s
      - name: Analog A3
        id: analog_a3
        filters:
          - throttle: 2s
      - name: Analog A4
        id: analog_a4
        filters:
          - throttle: 2s
      - name: Analog A5
        id: analog_a5
        filters:
          - throttle: 2s
      - name: Analog A6
        id: analog_a6
        filters:
          - throttle: 2s
      - name: Analog A7
        id: analog_a7
        filters:
          - throttle: 2s
      - name: Analog A8
        id: analog_a8
        filters:
          - throttle: 2s
      - name: Analog A9
        id: analog_a9
        filters:
          - throttle: 2s
      - name: Analog A10
        id: analog_a10
        filters:
          - throttle: 2s
      - name: Analog A11
        id: analog_a11
        filters:
          - throttle: 2s

@NonaSuomy
Copy link
Author

NonaSuomy commented Oct 30, 2022

I'm not really sure what I'm doing but I got more than 0's by playing with the binary values. In the new Arduino IDE 2.0 I could hover over the pin values and then it would show me the correct pin values:

//A11 22 0x16 10110;
//A0 21 0x15 10101;
//A1 20 0x14 10100;
//A2 19 0x13 10011;
//A3 18 0x12 10010;
//A4 17 0x11 10001;
//A5 16 0x10 10000;
//A6 15 0xf 1111;
//A7 14 0xe 1110;
//A8 13 0xd 1101;
//A9 12 0xc 1100;
//A10 10 0xa 1010;

The values are dumping all over the place now so I'm sure I'm messing up the way it processes the analog values now with its bitwise operation.

Only pin F5 connected:

[01:52:11][D][sensor:127]: 'Analog A0': Sending state 32.00000  with 0 decimals of accuracy
[01:52:12][D][sensor:127]: 'Analog A1': Sending state 32.00000  with 0 decimals of accuracy
[01:52:12][D][sensor:127]: 'Analog A2': Sending state 32.00000  with 0 decimals of accuracy
[01:52:12][D][sensor:127]: 'Analog A3': Sending state 32.00000  with 0 decimals of accuracy
[01:52:13][D][sensor:127]: 'Analog A4': Sending state 1023.00000  with 0 decimals of accuracy
[01:52:13][D][sensor:127]: 'Analog A5': Sending state 977.00000  with 0 decimals of accuracy
[01:52:13][D][sensor:127]: 'Analog A6': Sending state 1023.00000  with 0 decimals of accuracy
[01:52:13][D][sensor:127]: 'Analog A7': Sending state 1023.00000  with 0 decimals of accuracy
[01:52:13][D][sensor:127]: 'Analog A8': Sending state 943.00000  with 0 decimals of accuracy
[01:52:13][D][sensor:127]: 'Analog A9': Sending state 896.00000  with 0 decimals of accuracy
[01:52:13][D][sensor:127]: 'Analog A10': Sending state 894.00000  with 0 decimals of accuracy
[01:52:13][D][sensor:127]: 'Analog A11': Sending state 848.00000  with 0 decimals of accuracy

No pins connected:

[01:54:02][D][sensor:127]: 'Analog A0': Sending state 32.00000  with 0 decimals of accuracy
[01:54:03][D][sensor:127]: 'Analog A1': Sending state 32.00000  with 0 decimals of accuracy
[01:54:03][D][sensor:127]: 'Analog A2': Sending state 32.00000  with 0 decimals of accuracy
[01:54:03][D][sensor:127]: 'Analog A3': Sending state 32.00000  with 0 decimals of accuracy
[01:54:03][D][sensor:127]: 'Analog A4': Sending state 32.00000  with 0 decimals of accuracy
[01:54:04][D][sensor:127]: 'Analog A5': Sending state 143.00000  with 0 decimals of accuracy
[01:54:04][D][sensor:127]: 'Analog A6': Sending state 159.00000  with 0 decimals of accuracy
[01:54:04][D][sensor:127]: 'Analog A7': Sending state 150.00000  with 0 decimals of accuracy
[01:54:04][D][sensor:127]: 'Analog A8': Sending state 146.00000  with 0 decimals of accuracy
[01:54:04][D][sensor:127]: 'Analog A9': Sending state 32.00000  with 0 decimals of accuracy
[01:54:04][D][sensor:127]: 'Analog A10': Sending state 151.00000  with 0 decimals of accuracy
[01:54:04][D][sensor:127]: 'Analog A11': Sending state 146.00000  with 0 decimals of accuracy

Full code

/*
Ports:
	0 0 .. 13 13
	A0: 14, A1: 15, A2: 16, A3: 17: A4: 18: A5: 19: A6: 20, A7: 21
	port bits: 5 ... 0..32
	0:   0: 00000
	1:	 1:	00001
	A7: 21: 10101
*/

#include <Arduino.h>
#include <Wire.h>

//#define DEBUG 1 // remove debug so pin 0 and 1 can be used for IO
//#define DEBUG_READ 1
#define I2C_ADDRESS 9

void onRequest();
void onReceive(int);

void setup()
{
#ifdef DEBUG
  Serial.begin(115200);
  Serial.println(F("Init "));
#endif

  analogReference(INTERNAL);

  Wire.begin(I2C_ADDRESS);
  Wire.onRequest(onRequest);
  Wire.onReceive(onReceive);

#ifdef DEBUG
  Serial.println(F("Wire ok"));
#endif
}

void loop()
{
  //int temp = analogRead(A1);
  //Serial.println(temp);
}

volatile byte buffer[3];
volatile byte len = 1;

#define DIGITAL_READ(b, pin, mask) \
  if (digitalRead(pin))            \
    buffer[b] |= mask;

void readDigital()
{
  len = 3;
  buffer[0] = 0;
  DIGITAL_READ(0, PIN_B0, 1);  // Digital
  DIGITAL_READ(0, PIN_B1, 2);  // Digital
  DIGITAL_READ(0, PIN_B2, 4);  // Digital
  DIGITAL_READ(0, PIN_B3, 8);  // Digital
  DIGITAL_READ(0, PIN_B7, 16); // Digital
  DIGITAL_READ(0, PIN_E6, 32); // Digital
  
  //I2C Teensy 2.0
  //DIGITAL_READ(0, PIN_D0, 32); // Digital
  //DIGITAL_READ(0, PIN_D1, 64); // Digital

  DIGITAL_READ(0, PIN_D2, 128);  // Digital

  buffer[1] = 0;
  DIGITAL_READ(1, PIN_D3, 1);   // Digital
  DIGITAL_READ(1, PIN_C6, 2);   // Digital
  DIGITAL_READ(1, PIN_C7, 4);   // Digital
  DIGITAL_READ(1, PIN_D6, 8);   // Analog
  DIGITAL_READ(1, PIN_D7, 16);  // Analog
  DIGITAL_READ(1, PIN_B4, 32);  // Analog
  DIGITAL_READ(1, PIN_B5, 64);  // Analog
  DIGITAL_READ(1, PIN_B6, 128); // Analog

  buffer[2] = 0;
  DIGITAL_READ(2, PIN_F7, 1); // Analog
  DIGITAL_READ(2, PIN_F6, 2); // Analog

// I2C
  DIGITAL_READ(2, PIN_F5, 4); // Analog
  DIGITAL_READ(2, PIN_F4, 8); // Analog

  DIGITAL_READ(2, PIN_F1, 16); // Analog
  DIGITAL_READ(2, PIN_F0, 32); // Analog
  DIGITAL_READ(2, PIN_D4, 64); // Analog
  DIGITAL_READ(2, PIN_D5, 128); // Digital

//A11 22 0x16 10110;
//A0 21 0x15 10101;
//A1 20 0x14 10100;
//A2 19 0x13 10011;
//A3 18 0x12 10010;
//A4 17 0x11 10001;
//A5 16 0x10 10000;
//A6 15 0xf 1111;
//A7 14 0xe 1110;
//A8 13 0xd 1101;
//A9 12 0xc 1100;
//A10 10 0xa 1010;

  //buffer[3] = 0;
  //DIGITAL_READ(3, PIN_E6, 1);
  
// DIGITAL READ not supports on A3 .. A7
#ifdef DEBUG_READ
  Serial.print(F("Read 3 bytes: "));
  Serial.print(buffer[0]);
  Serial.print(' ');
  Serial.print(buffer[1]);
  Serial.print(' ');
  Serial.println(buffer[2]);

#endif
}
void readAnalog(int pin)
{
  int val = analogRead(A9 + pin);
  len = 2;
  buffer[0] = val & 0xFF;
  buffer[1] = (val >> 8) & 0b11;
#ifdef DEBUG_READ
  Serial.print(F("Read analog pin "));
  Serial.println(pin);
#endif
}

void onRequest()
{
  Wire.write(const_cast<uint8_t *>(buffer), len);
}

#define CMD_DIGITAL_READ 0x0

#define CMD_WRITE_ANALOG 0x2
#define CMD_WRITE_DIGITAL_HIGH 0x3
#define CMD_WRITE_DIGITAL_LOW 0x4

#define CMD_SETUP_PIN_OUTPUT 0x5
#define CMD_SETUP_PIN_INPUT_PULLUP 0x6
#define CMD_SETUP_PIN_INPUT 0x7

// 8 analog registers.. A0 to A7
// A4 and A5 not supported due to I2C
#define CMD_ANALOG_READ_A9 0b1100 // 0x8
// ....
#define CMD_ANALOG_READ_A0 0b10101 // 0xF

#define CMD_SETUP_ANALOG_INTERNAL 0x10
#define CMD_SETUP_ANALOG_DEFAULT 0x11

void onReceive(int numBytes)
{
#ifdef DEBUG_READ
  Serial.print("Received bytes: ");
  Serial.println(numBytes);
#endif
  int cmd = Wire.read();

  switch (cmd)
  {
  case CMD_DIGITAL_READ:
    readDigital();
    break;
  }

  if (cmd >= CMD_ANALOG_READ_A9 && cmd <= CMD_ANALOG_READ_A0)
  {
    readAnalog(cmd & 0b111);
    return;
  }

  int pin = Wire.read();

  switch (cmd)
  {
  case CMD_WRITE_DIGITAL_HIGH:
  case CMD_WRITE_DIGITAL_LOW:
  {
    bool output = cmd == CMD_WRITE_DIGITAL_HIGH;
    digitalWrite(pin, output);
#ifdef DEBUG
    Serial.print(F("Pin "));
    Serial.print(pin);
    Serial.println(output ? F(" HIGH") : F(" LOW"));
#endif
    break;
  }
  case CMD_WRITE_ANALOG:
  {
    int val = Wire.read() & (Wire.read() << 8);
    analogWrite(pin, val);
#ifdef DEBUG
    Serial.print(F("Pin "));
    Serial.print(pin);
    Serial.print(F(" Analog write "));
    Serial.println(val);
#endif
    break;
  }
  case CMD_SETUP_PIN_OUTPUT:
    pinMode(pin, OUTPUT);
#ifdef DEBUG
    Serial.print(F("Pin "));
    Serial.print(pin);
    Serial.println(F(" OUTPUT"));
#endif
    break;
  case CMD_SETUP_PIN_INPUT:
    pinMode(pin, INPUT);
#ifdef DEBUG
    Serial.print(F("Pin "));
    Serial.print(pin);
    Serial.println(F("INPUT"));
#endif
    break;
  case CMD_SETUP_PIN_INPUT_PULLUP:
    pinMode(pin, INPUT_PULLUP);
#ifdef DEBUG
    Serial.print(F("Pin "));
    Serial.print(pin);
    Serial.println(F("INPUT PULLUP"));
#endif
    break;
  case CMD_SETUP_ANALOG_INTERNAL:
    analogReference(INTERNAL);
//#ifdef DEBUG
    //Serial.println(F("Analog reference INTERNAL"));
//#endif
    break;
  case CMD_SETUP_ANALOG_DEFAULT:
    analogReference(DEFAULT);
//#ifdef DEBUG
    //Serial.println(F("Analog reference DEFAULT"));
//#endif
    break;
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants