This commit is contained in:
Christian Werner 2025-09-28 20:11:02 +02:00
parent d9c3891bec
commit 40d5e5fd10
12 changed files with 280 additions and 18 deletions

Binary file not shown.

View File

@ -12,8 +12,10 @@
#define WRITE 2 #define WRITE 2
char count = 0; char count = 0;
unsigned short delayAmount = 100; unsigned short delayAmount = 2;
char textToSent[] = "The Commodore 64, also known as the C64, is an 8-bit home computer introduced in January 1982 by Commodore International. It has been listed in the Guinness World Records as the best-selling desktop computer model of all time, with independent estimates placing the number sold between 12.5 and 17 million units."; const char* ArduinoPingMsg = "ping F28339B0-78C6-4445-905A-76F77F667D95";
const char* ArduinoPongMsg = "pong F28339B0-78C6-4445-905A-76F77F667D95";
char mode; char mode;
@ -68,13 +70,27 @@ void initMode(const char modeToSet) {
} }
String waitForLine() {
return Serial.readStringUntil('\n');
}
void waitForPing() {
while (true) {
while (Serial.available() == 0) {} //wait for data available
String pingStr = waitForLine(); //read until timeout
pingStr.trim();
if (pingStr == ArduinoPingMsg) {
Serial.println(ArduinoPongMsg);
break;
}
}
}
void setup() { void setup() {
delay(2000);
mode = STANDBY; mode = STANDBY;
initMode(mode); initMode(mode);
Serial.begin(9600); Serial.begin(9600);
waitForPing();
} }
void send4Bit(char c) { void send4Bit(char c) {
@ -94,8 +110,8 @@ void send4Bit(char c) {
digitalWrite(AR, HIGH); digitalWrite(AR, HIGH);
// while (digitalRead(CR) == LOW) {} while (digitalRead(CR) == LOW) {}
// while (digitalRead(CR) == HIGH) {} while (digitalRead(CR) == HIGH) {}
delay(delayAmount); delay(delayAmount);
@ -120,8 +136,7 @@ void sendByte(char a, char byte) {
send4Bit(lower); send4Bit(lower);
} }
void startWrite() { void startWrite(String str) {
Serial.print("start\n");
mode = WRITE; mode = WRITE;
initMode(mode); initMode(mode);
digitalWrite(AR, LOW); digitalWrite(AR, LOW);
@ -129,7 +144,7 @@ void startWrite() {
int i = 0; int i = 0;
char c, sc; char c, sc;
do { do {
c = textToSent[i]; c = str[i];
sc = getScreenCode(c); sc = getScreenCode(c);
i++; i++;
sendByte(c, sc); sendByte(c, sc);
@ -147,16 +162,23 @@ void startWrite() {
void loop() { void loop() {
if (mode == WRITE) { String line = waitForLine();
} else if (mode == READ) { if (line.length() > 0) {
startWrite(line);
} else {
startWrite();
} }
Serial.print("\nAAAAAAAA\n");
delay(1000); // if (mode == WRITE) {
//
// } else if (mode == READ) {
//
// } else {
// startWrite();
// }
//
// Serial.print("\nAAAAAAAA\n");
// delay(1000);
} }

View File

@ -270,7 +270,7 @@ void recieveTest(char* title) {
lower = 16; lower = 16;
upper = 16; upper = 16;
*dirPtr = 0b11110000; *dirPtr = 0b11111000;
*dataPtr = 0; *dataPtr = 0;
while (1) { while (1) {

2
web/c64_inteface/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
bin/
obj/

View File

@ -0,0 +1,7 @@
namespace c64_inteface;
public class ArduinoMessageContainer
{
public string Message { get; set; } = "";
public bool Ready { get; set; } = false;
}

View File

@ -0,0 +1,124 @@
using System.IO.Ports;
namespace c64_inteface;
public class MonitorBackgroundService : IHostedService, IDisposable
{
private const string ArduinoId = "F28339B0-78C6-4445-905A-76F77F667D95";
private const string ArduinoPingMsg = "ping " + ArduinoId + "\n";
private const string ArduinoPongMsg = "pong " + ArduinoId;
private readonly ILogger<MonitorBackgroundService> _logger;
private readonly ArduinoMessageContainer _arduinoMessageContainer;
private SerialPort? _arduinoPort;
public MonitorBackgroundService(ILogger<MonitorBackgroundService> logger, ArduinoMessageContainer arduinoMessageContainer)
{
_logger = logger;
_arduinoMessageContainer = arduinoMessageContainer;
}
public Task StartAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("{Service} running.", nameof(MonitorBackgroundService));
Task.Run(() => RunServiceAsync(stoppingToken), stoppingToken);
return Task.CompletedTask;
}
private async Task DoWork(CancellationToken cancellationToken)
{
_logger.LogInformation("DoWork running...");
while (!cancellationToken.IsCancellationRequested)
{
if (_arduinoMessageContainer.Ready)
{
try
{
_logger.LogInformation("Sending message: {Message}", _arduinoMessageContainer.Message);
_arduinoPort?.WriteLine(_arduinoMessageContainer.Message);
_arduinoMessageContainer.Ready = false;
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
private async Task RunServiceAsync(CancellationToken cancellationToken)
{
await FindArduinoPort(cancellationToken);
await DoWork(cancellationToken);
}
public Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("{Service} is stopping.", nameof(MonitorBackgroundService));
return Task.CompletedTask;
}
private async Task FindArduinoPort(CancellationToken cancellationToken)
{
while (_arduinoPort is null && !cancellationToken.IsCancellationRequested)
{
var ports = SerialPort.GetPortNames().ToList();
_logger.LogInformation("available ports: {Ports}", ports);
foreach (var portName in ports)
{
var port = new SerialPort(portName, 9600);
port.ReadTimeout = 1000;
try
{
port.Open();
await Task.Delay(2000, cancellationToken);
}
catch (IOException)
{
continue;
}
port.WriteLine(ArduinoPingMsg);
try
{
var response = port.ReadLine();
_logger.LogInformation(response);
if (!response.Contains(ArduinoPongMsg))
{
_logger.LogInformation("{portName} not my arduino", portName);
port.Close();
continue;
}
}
catch (Exception ex)
{
_logger.LogError(ex, ex.Message);
_logger.LogInformation("{portName} did not respond", portName);
continue;
}
_logger.LogInformation("Arduino found on {portName}", portName);
_arduinoPort = port;
return;
}
await Task.Delay(1000, cancellationToken);
}
}
public void Dispose()
{
_arduinoPort?.Close();
_arduinoPort?.Dispose();
}
}

View File

@ -0,0 +1,31 @@
using c64_inteface;
using Microsoft.AspNetCore.Http.HttpResults;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
builder.Services.AddSingleton<ArduinoMessageContainer>();
builder.Services.AddHostedService<MonitorBackgroundService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseHttpsRedirection();
app.MapGet("/api/{message}", (string message, ArduinoMessageContainer arduinoMessageContainer) =>
{
arduinoMessageContainer.Message = message.Trim();
arduinoMessageContainer.Ready = true;
return true;
})
.WithName("SendMessageToArduino");
app.Run();

View File

@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5216",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7088;http://localhost:5216",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.9"/>
<PackageReference Include="System.IO.Ports" Version="9.0.9" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "c64_inteface", "c64_inteface.csproj", "{53F85B44-8B21-41EE-88AE-A9BBDB3CED0A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{53F85B44-8B21-41EE-88AE-A9BBDB3CED0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{53F85B44-8B21-41EE-88AE-A9BBDB3CED0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{53F85B44-8B21-41EE-88AE-A9BBDB3CED0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{53F85B44-8B21-41EE-88AE-A9BBDB3CED0A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal